[PATCH 08/12] libusbg: Allow to set all gadget attrs using one function.

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

 



Having specialized functions for each attribute may be
sometime inconvenient to use. Provide also function
whihc allows to set attribute selected by parameter.

Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx>
---
 include/usbg/usbg.h |   53 +++++++++++++++++++++++++++++++++++++
 src/usbg.c          |   73 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 126 insertions(+)

diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index 3f5d561..2c191eb 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -88,6 +88,22 @@ typedef struct usbg_function usbg_function;
 typedef struct usbg_binding usbg_binding;
 
 /**
+ * @typedef usbg_gadget_attr
+ * @brief Gadget attributes which can be set using
+ * usbg_set_gadget_attr() function.
+ */
+typedef enum {
+	BCD_USB = 0,
+	B_DEVICE_CLASS,
+	B_DEVICE_SUB_CLASS,
+	B_DEVICE_PROTOCOL,
+	B_MAX_PACKET_SIZE_0,
+	ID_VENDOR,
+	ID_PRODUCT,
+	BCD_DEVICE,
+} usbg_gadget_attr;
+
+/**
  * @typedef usbg_gadget_attrs
  * @brief USB gadget device attributes
  */
@@ -395,6 +411,43 @@ extern int usbg_create_gadget(usbg_state *s, const char *name,
 			      usbg_gadget **g);
 
 /**
+ * @brief Get string representing selected gadget attribute
+ * @param attr code of selected attrobute
+ * @return String suitable for given attribute or NULL if such
+ * string has not been found
+ */
+extern const char *usbg_get_gadget_attr_str(usbg_gadget_attr attr);
+
+/**
+ * @brief Lookup attr code based on its name
+ * @param name of attribute
+ * @return code of suitable attribute or usbg_error
+ */
+int usbg_lookup_gadget_attr(const char *name);
+
+/**
+ * @brief Set selected attribute to value
+ * @param g Pointer to gadget
+ * @param attr Code of selected attribute
+ * @param val value to be set
+ * @return 0 on success, usbg_error otherwise
+ * @note val is of type int but value provided to this function should
+ * be suitable to place it in type dedicated for selected attr (uint16 or uint8)
+ */
+extern int usbg_set_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr, int val);
+
+/**
+ * @brief Get value of selected attribute
+ * @param g Pointer to gadget
+ * @param attr Code of selected attribute
+ * @return Value of selected attribute (always above zero) or
+ * usbg_error if error occurred.
+ * @note User should use only lowest one or two bytes as attribute value
+ * depending on attribute size (see usbg_gadget_attrs for details).
+ */
+extern int usbg_get_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr);
+
+/**
  * @brief Set the USB gadget attributes
  * @param g Pointer to gadget
  * @param g_attrs Gadget attributes
diff --git a/src/usbg.c b/src/usbg.c
index bd63790..cd2179e 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -111,6 +111,18 @@ const char *function_names[] =
 	"ffs",
 };
 
+const char *gadget_attr_names[] =
+{
+	"bcdUSB",
+	"bDeviceClass",
+	"bDeviceSubClass",
+	"bDeviceProtocol",
+	"bMaxPacketSize0",
+	"idVendor",
+	"idProduct",
+	"bcdDevice"
+};
+
 #define ERROR(msg, ...) do {\
                         fprintf(stderr, "%s()  "msg" \n", \
                                 __func__, ##__VA_ARGS__);\
@@ -158,6 +170,7 @@ static int usbg_translate_error(int error)
 	case ENOTDIR:
 		ret = USBG_ERROR_NOT_FOUND;
 		break;
+	case ERANGE:
 	case EINVAL:
 	case USBG_ERROR_INVALID_PARAM:
 		ret = USBG_ERROR_INVALID_PARAM;
@@ -323,6 +336,29 @@ const const char *usbg_get_function_type_str(usbg_function_type type)
 			function_names[type] : NULL;
 }
 
+int usbg_lookup_gadget_attr(const char *name)
+{
+	int i = 0;
+	int max = sizeof(gadget_attr_names)/sizeof(char *);
+
+	if (!name)
+		return USBG_ERROR_INVALID_PARAM;
+
+	do {
+		if (!strcmp(name, gadget_attr_names[i]))
+			return i;
+		i++;
+	} while (i != max);
+
+	return USBG_ERROR_NOT_FOUND;
+}
+
+const const char *usbg_get_gadget_attr_str(usbg_gadget_attr attr)
+{
+	return attr >= 0 && attr < sizeof(gadget_attr_names)/sizeof(char *) ?
+			gadget_attr_names[attr] : NULL;
+}
+
 static usbg_error usbg_split_function_instance_type(const char *full_name,
 		usbg_function_type *f_type, const char **instance)
 {
@@ -519,6 +555,7 @@ static int usbg_write_int(const char *path, const char *name, const char *file,
 }
 
 #define usbg_write_dec(p, n, f, v)	usbg_write_int(p, n, f, v, "%d\n")
+#define usbg_write_hex(p, n, f, v)	usbg_write_int(p, n, f, v, "0x%x\n")
 #define usbg_write_hex16(p, n, f, v)	usbg_write_int(p, n, f, v, "0x%04x\n")
 #define usbg_write_hex8(p, n, f, v)	usbg_write_int(p, n, f, v, "0x%02x\n")
 
@@ -1746,6 +1783,42 @@ int usbg_get_gadget_udc(usbg_gadget *g, char *buf, size_t len)
 	return USBG_SUCCESS;
 }
 
+int usbg_set_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr, int val)
+{
+	const char *attr_name;
+	int ret = USBG_ERROR_INVALID_PARAM;
+
+	if (!g)
+		goto out;
+
+	attr_name = usbg_get_gadget_attr_str(attr);
+	if (!attr_name)
+		goto out;
+
+	ret = usbg_write_hex(g->path, g->name, attr_name, val);
+
+out:
+	return ret;
+}
+
+int usbg_get_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr)
+{
+	const char *attr_name;
+	int ret = USBG_ERROR_INVALID_PARAM;
+
+	if (!g)
+		goto out;
+
+	attr_name = usbg_get_gadget_attr_str(attr);
+	if (!attr_name)
+		goto out;
+
+	usbg_read_hex(g->path, g->name, attr_name, &ret);
+
+out:
+	return ret;
+}
+
 int usbg_set_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs)
 {
 	int ret;
-- 
1.7.9.5

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