that's useful information to expose to userland. NYET-Signed-off-by: Felipe Balbi <balbi@xxxxxx> --- drivers/usb/gadget/udc-core.c | 22 ++++++++++++++++ include/linux/usb/gadget.h | 56 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 0 deletions(-) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 2031c11..6df2df7 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -102,6 +102,16 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); /* ------------------------------------------------------------------------- */ +void usb_gadget_set_status(struct usb_gadget *gadget, + enum usb_device_status status) +{ + gadget->status = status; + sysfs_notify(&gadget->dev.kobj, NULL, "status"); +} +EXPORT_SYMBOL_GPL(usb_gadget_set_status); + +/* ------------------------------------------------------------------------- */ + /** * usb_gadget_start - tells usb device controller to start up * @gadget: The gadget we want to get started @@ -424,6 +434,17 @@ static ssize_t usb_udc_softconn_store(struct device *dev, } static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); +static ssize_t usb_gadget_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct usb_udc *udc = container_of(dev, struct usb_udc, dev); + struct usb_gadget *gadget = udc->gadget; + + return snprintf(buf, PAGE_SIZE, "%s\n", + usb_device_status_string(gadget->status)); +} +static DEVICE_ATTR(status, S_IRUGO, usb_gadget_status_show, NULL); + #define USB_UDC_SPEED_ATTR(name, param) \ ssize_t usb_udc_##param##_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ @@ -467,6 +488,7 @@ static USB_UDC_ATTR(a_alt_hnp_support); static struct attribute *usb_udc_attrs[] = { &dev_attr_srp.attr, &dev_attr_soft_connect.attr, + &dev_attr_status.attr, &dev_attr_current_speed.attr, &dev_attr_maximum_speed.attr, diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 7d64f89..6aa9fc2 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -478,6 +478,53 @@ struct usb_gadget_ops { int (*stop)(struct usb_gadget_driver *); }; +enum usb_device_status { + USB_STATUS_IDLE, + USB_STATUS_CONNECTED, + USB_STATUS_RESETTING, + + USB_STATUS_DEFAULT, + USB_STATUS_ADDRESSED, + USB_STATUS_UNCONFIGURED, + USB_STATUS_CONFIGURED, + + USB_STATUS_SUSPENDING, + USB_STATUS_SUSPENDED, + USB_STATUS_RESUMING, + USB_STATUS_RESUMED, +}; + +static inline const char * +usb_device_status_string(enum usb_device_status status) +{ + switch (status) { + case USB_STATUS_IDLE: + return "idle"; + case USB_STATUS_CONNECTED: + return "connected"; + case USB_STATUS_RESETTING: + return "resetting"; + case USB_STATUS_DEFAULT: + return "default"; + case USB_STATUS_ADDRESSED: + return "addressed"; + case USB_STATUS_UNCONFIGURED: + return "unconfigured"; + case USB_STATUS_CONFIGURED: + return "configured"; + case USB_STATUS_SUSPENDING: + return "suspending"; + case USB_STATUS_SUSPENDED: + return "suspended"; + case USB_STATUS_RESUMING: + return "resuming"; + case USB_STATUS_RESUMED: + return "resumed"; + default: + return "UNKNOWN"; + } +} + /** * struct usb_gadget - represents a usb slave device * @ops: Function pointers used to access hardware-specific operations. @@ -487,6 +534,7 @@ struct usb_gadget_ops { * @speed: Speed of current connection to USB host. * @max_speed: Maximal speed the UDC can handle. UDC must support this * and all slower speeds. + * @status: the status we are now (connected, suspended, resuming, etc) * @sg_supported: true if we can handle scatter-gather * @is_otg: True if the USB device port uses a Mini-AB jack, so that the * gadget driver must provide a USB OTG descriptor. @@ -528,6 +576,7 @@ struct usb_gadget { struct list_head ep_list; /* of usb_ep */ enum usb_device_speed speed; enum usb_device_speed max_speed; + enum usb_device_status status; unsigned sg_supported:1; unsigned is_otg:1; unsigned is_a_peripheral:1; @@ -960,6 +1009,13 @@ extern void usb_gadget_unmap_request(struct usb_gadget *gadget, /*-------------------------------------------------------------------------*/ +/* utility to set gadget status properly */ + +extern void usb_gadget_set_status(struct usb_gadget *gadget, + enum usb_device_status status); + +/*-------------------------------------------------------------------------*/ + /* utility wrapping a simple endpoint selection policy */ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, -- 1.7.8.rc3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html