that's useful information to expose to userland. NYET-Signed-off-by: Felipe Balbi <balbi@xxxxxx> --- drivers/usb/gadget/udc-core.c | 52 +++++++++++++++++++++++++++++++++++++++++++ include/linux/usb/gadget.h | 11 +++++++++ 2 files changed, 63 insertions(+) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index b6c9110..15e484f 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -27,6 +27,8 @@ #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> +#include <uapi/linux/usb/ch9.h> + /** * struct usb_udc - describes one usb device controller * @driver - the gadget driver pointer. For use by the class code @@ -50,6 +52,34 @@ static DEFINE_MUTEX(udc_lock); /* ------------------------------------------------------------------------- */ +static const char *usb_device_state_string(enum usb_device_state state) +{ + switch(state) { + case USB_STATE_NOTATTACHED: + return "not attached"; + case USB_STATE_ATTACHED: + return "attached"; + case USB_STATE_POWERED: + return "powered"; + case USB_STATE_RECONNECTING: + return "reconnecting"; + case USB_STATE_UNAUTHENTICATED: + return "unauthenticated"; + case USB_STATE_DEFAULT: + return "default"; + case USB_STATE_ADDRESS: + return "addresssed"; + case USB_STATE_CONFIGURED: + return "configured"; + case USB_STATE_SUSPENDED: + return "suspended"; + default: + return "UNKNOWN"; + } +} + +/* ------------------------------------------------------------------------- */ + int usb_gadget_map_request(struct usb_gadget *gadget, struct usb_request *req, int is_in) { @@ -101,6 +131,16 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); /* ------------------------------------------------------------------------- */ +void usb_gadget_set_state(struct usb_gadget *gadget, + enum usb_device_state state) +{ + gadget->state = state; + sysfs_notify(&gadget->dev.kobj, NULL, "status"); +} +EXPORT_SYMBOL_GPL(usb_gadget_set_state); + +/* ------------------------------------------------------------------------- */ + /** * usb_gadget_udc_start - tells usb device controller to start up * @gadget: The gadget we want to get started @@ -407,6 +447,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_state_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_state_string(gadget->state)); +} +static DEVICE_ATTR(state, S_IRUGO, usb_gadget_state_show, NULL); + #define USB_UDC_SPEED_ATTR(name, param) \ ssize_t usb_udc_##param##_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ @@ -440,6 +491,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_state.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 2e297e8..e8a24de 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -24,6 +24,8 @@ #include <linux/types.h> #include <linux/usb/ch9.h> +#include <uapi/linux/usb/ch9.h> + struct usb_ep; /** @@ -482,6 +484,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. + * @state: the state we are now (attached, suspended, configured, 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. @@ -525,6 +528,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_state state; unsigned sg_supported:1; unsigned is_otg:1; unsigned is_a_peripheral:1; @@ -959,6 +963,13 @@ extern void usb_gadget_unmap_request(struct usb_gadget *gadget, /*-------------------------------------------------------------------------*/ +/* utility to set gadget status properly */ + +extern void usb_gadget_set_state(struct usb_gadget *gadget, + enum usb_device_state state); + +/*-------------------------------------------------------------------------*/ + /* utility wrapping a simple endpoint selection policy */ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, -- 1.8.1.rc1.5.g7e0651a -- 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