[PATCH 2/2] usb: gadget: configfs: for_device attribute in configuration directory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Provide interface for setting for_device function designated in a
configuration for handling setup requests directed to device.

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx>
---
 drivers/usb/gadget/configfs.c | 50 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index d25f9f3..9648d2a 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -430,7 +430,6 @@ static int config_usb_cfg_unlink(
 	struct usb_function_instance *fi = container_of(group,
 			struct usb_function_instance, group);
 	struct usb_function *f;
-
 	/*
 	 * ideally I would like to forbid to unlink functions while a gadget is
 	 * bound to an UDC. Since this isn't possible at the moment, we simply
@@ -444,6 +443,8 @@ static int config_usb_cfg_unlink(
 
 	list_for_each_entry(f, &cfg->func_list, list) {
 		if (f->fi == fi) {
+			if (f == cfg->c.for_device)
+				cfg->c.for_device = NULL;
 			list_del(&f->list);
 			usb_put_function(f);
 			mutex_unlock(&gi->lock);
@@ -509,6 +510,51 @@ static ssize_t gadget_config_desc_bmAttributes_store(struct config_usb_cfg *cfg,
 	return len;
 }
 
+static ssize_t gadget_config_desc_for_device_show(struct config_usb_cfg *cfg,
+		char *page)
+{
+	return sprintf(page, "%s\n", cfg->c.for_device ?
+			cfg->c.for_device->fi->group.cg_item.ci_name : "");
+}
+
+static ssize_t gadget_config_desc_for_device_store(struct config_usb_cfg *cfg,
+		const char *page, size_t len)
+{
+	struct usb_composite_dev *cdev = cfg->c.cdev;
+	struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
+	struct usb_function *f = NULL;
+	ssize_t ret = -EBUSY;
+	char *name;
+
+	name = kstrdup(page, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+	if (name[len - 1] == '\n')
+		name[len - 1] = '\0';
+
+	mutex_lock(&gi->lock);
+	if (gi->udc_name)
+		goto out;
+
+	if (!len || !*page || *page == '\n')
+		goto set_ret;
+
+	list_for_each_entry(f, &cfg->func_list, list)
+		if (!strncmp(f->fi->group.cg_item.ci_name, name, len))
+			break;
+	if (&f->list == &cfg->func_list) {
+		ret = -EINVAL;
+		goto out;
+	}
+set_ret:
+	ret = len;
+	cfg->c.for_device = f;
+out:
+	mutex_unlock(&gi->lock);
+	kfree(name);
+	return ret;
+}
+
 #define CFG_CONFIG_DESC_ITEM_ATTR(name)	\
 	static struct config_usb_cfg_attribute gadget_usb_cfg_##name = \
 		__CONFIGFS_ATTR(name,  S_IRUGO | S_IWUSR,		\
@@ -517,10 +563,12 @@ static ssize_t gadget_config_desc_bmAttributes_store(struct config_usb_cfg *cfg,
 
 CFG_CONFIG_DESC_ITEM_ATTR(MaxPower);
 CFG_CONFIG_DESC_ITEM_ATTR(bmAttributes);
+CFG_CONFIG_DESC_ITEM_ATTR(for_device);
 
 static struct configfs_attribute *gadget_config_attrs[] = {
 	&gadget_usb_cfg_MaxPower.attr,
 	&gadget_usb_cfg_bmAttributes.attr,
+	&gadget_usb_cfg_for_device.attr,
 	NULL,
 };
 
-- 
1.9.1

--
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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux