[PATCH v2 15/23] libusbg: Add return value to usb function related functions.

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

 



Each usbg_set_*() may fail so it should have a return value
to notify user about reason of failure.

To be consistent with rest of API usbg_create_function()
should also return error code to notify user about reasons
of failure instead of binary information (NULL or not).

Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx>
---
 examples/gadget-acm-ecm.c |   12 ++--
 include/usbg/usbg.h       |   20 ++++---
 src/usbg.c                |  140 ++++++++++++++++++++++++++++-----------------
 3 files changed, 108 insertions(+), 64 deletions(-)

diff --git a/examples/gadget-acm-ecm.c b/examples/gadget-acm-ecm.c
index b1131b4..678514c 100644
--- a/examples/gadget-acm-ecm.c
+++ b/examples/gadget-acm-ecm.c
@@ -69,20 +69,20 @@ int main(void)
 		goto out2;
 	}
 
-	f_acm0 = usbg_create_function(g, F_ACM, "usb0", NULL);
-	if (!f_acm0) {
+	usbg_ret = usbg_create_function(g, F_ACM, "usb0", NULL, &f_acm0);
+	if (usbg_ret != USBG_SUCCESS) {
 		fprintf(stderr, "Error creating acm0 function\n");
 		goto out2;
 	}
 
-	f_acm1 = usbg_create_function(g, F_ACM, "usb1", NULL);
-	if (!f_acm1) {
+	usbg_ret = usbg_create_function(g, F_ACM, "usb1", NULL, &f_acm1);
+	if (usbg_ret != USBG_SUCCESS) {
 		fprintf(stderr, "Error creating acm1 function\n");
 		goto out2;
 	}
 
-	f_ecm = usbg_create_function(g, F_ECM, "usb0", NULL);
-	if (!f_ecm) {
+	usbg_ret = usbg_create_function(g, F_ECM, "usb0", NULL, &f_acm1);
+	if (usbg_ret != USBG_SUCCESS) {
 		fprintf(stderr, "Error creating ecm function\n");
 		goto out2;
 	}
diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index 17084bb..005f9eb 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -435,10 +435,12 @@ extern int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd);
  * @param type Type of function
  * @param instance Function instance name
  * @param f_attrs Function attributes to be set. If NULL setting is omitted.
- * @return Pointer to function or NULL if it cannot be created
+ * @param f Pointer to be filled with pointer to function
+ * @note Given strings are assumed to be in US English
+ * @return 0 on success usbg_error if error occurred
  */
-extern usbg_function *usbg_create_function(usbg_gadget *g, usbg_function_type type,
-		char *instance, usbg_function_attrs *f_attrs);
+extern int usbg_create_function(usbg_gadget *g, usbg_function_type type,
+		char *instance, usbg_function_attrs *f_attrs, usbg_function **f);
 
 /**
  * @brief Get function name length
@@ -640,29 +642,33 @@ extern usbg_function_attrs *usbg_get_function_attrs(usbg_function *f,
  * @brief Set attributes of given function
  * @param f Pointer to function
  * @param f_attrs Attributes to be set
+ * @return 0 on success, usbg_error if error occurred
  */
-extern void usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs);
+extern int usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs);
 
 /**
  * @brief Set USB function network device address
  * @param f Pointer to function
  * @param addr Pointer to Ethernet address
+ * @return 0 on success, usbg_error if error occurred
  */
-extern void usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *addr);
+extern int usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *addr);
 
 /**
  * @brief Set USB function network host address
  * @param f Pointer to function
  * @param addr Pointer to Ethernet address
+ * @return 0 on success, usbg_error if error occurred
  */
-extern void usbg_set_net_host_addr(usbg_function *f, struct ether_addr *addr);
+extern int usbg_set_net_host_addr(usbg_function *f, struct ether_addr *addr);
 
 /**
  * @brief Set USB function network qmult
  * @param f Pointer to function
  * @param qmult Queue length multiplier
+ * @return 0 on success, usbg_error if error occurred
  */
-extern void usbg_set_net_qmult(usbg_function *f, int qmult);
+extern int usbg_set_net_qmult(usbg_function *f, int qmult);
 
 /**
  * @def usbg_for_each_gadget(g, s)
diff --git a/src/usbg.c b/src/usbg.c
index 5a4202c..08cd397 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -1162,52 +1162,58 @@ int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd)
 	return ret;
 }
 
-usbg_function *usbg_create_function(usbg_gadget *g, usbg_function_type type,
-		char *instance, usbg_function_attrs *f_attrs)
+int usbg_create_function(usbg_gadget *g, usbg_function_type type,
+		char *instance, usbg_function_attrs *f_attrs, usbg_function **f)
 {
 	char fpath[USBG_MAX_PATH_LENGTH];
 	char name[USBG_MAX_STR_LENGTH];
-	usbg_function *f;
-	int ret;
+	usbg_function *func;
+	int ret = USBG_ERROR_INVALID_PARAM;
 
-	if (!g)
-		return NULL;
+	if (!g || !f)
+		return ret;
 
 	/**
 	 * @todo Check for legal function type
 	 */
 	sprintf(name, "%s.%s", function_names[type], instance);
-	f = usbg_get_function(g, name);
-	if (f) {
+	func = usbg_get_function(g, name);
+	if (func) {
 		ERROR("duplicate function name\n");
-		return NULL;
+		return USBG_ERROR_EXIST;
 	}
 
 	sprintf(fpath, "%s/%s/%s/%s", g->path, g->name, FUNCTIONS_DIR, name);
 
-	f = malloc(sizeof(usbg_function));
-	if (!f) {
-		ERRORNO("allocating function\n");
-		return NULL;
-	}
-
-	strcpy(f->name, name);
-	sprintf(f->path, "%s/%s/%s", g->path, g->name, FUNCTIONS_DIR);
-	f->type = type;
+	*f = malloc(sizeof(usbg_function));
+	func = *f;
+	if (func) {
+		strcpy(func->name, name);
+		sprintf(func->path, "%s/%s/%s", g->path, g->name, FUNCTIONS_DIR);
+		func->type = type;
 
-	ret = mkdir(fpath, S_IRWXU|S_IRWXG|S_IRWXO);
-	if (ret < 0) {
-		ERRORNO("%s\n", fpath);
-		free(f);
-		return NULL;
-	}
+		ret = mkdir(fpath, S_IRWXU | S_IRWXG | S_IRWXO);
 
-	if (f_attrs)
-		usbg_set_function_attrs(f, f_attrs);
+		if (!ret) {
+			/* Success */
+			ret = USBG_SUCCESS;
+			if (f_attrs)
+				ret = usbg_set_function_attrs(func, f_attrs);
+		} else {
+			ret = usbg_translate_error(errno);
+		}
 
-	INSERT_TAILQ_STRING_ORDER(&g->functions, fhead, name, f, fnode);
+		if (ret == USBG_SUCCESS)
+			INSERT_TAILQ_STRING_ORDER(&g->functions, fhead, name,
+				func, fnode);
+		else
+			usbg_free_function(func);
+	} else {
+		ERRORNO("allocating function\n");
+		ret = USBG_ERROR_NO_MEM;
+	}
 
-	return f;
+	return ret;
 }
 
 usbg_config *usbg_create_config(usbg_gadget *g, char *name,
@@ -1469,61 +1475,93 @@ usbg_function_attrs *usbg_get_function_attrs(usbg_function *f,
 	return f_attrs;
 }
 
-void usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs)
+int usbg_set_function_net_attrs(usbg_function *f, usbg_f_net_attrs *attrs)
 {
+	int ret = USBG_SUCCESS;
 	char *addr;
 
+	addr = ether_ntoa(&attrs->dev_addr);
+	ret = usbg_write_string(f->path, f->name, "dev_addr", addr);
+	if (ret != USBG_SUCCESS)
+		goto out;
+
+	addr = ether_ntoa(&attrs->host_addr);
+	ret = usbg_write_string(f->path, f->name, "host_addr", addr);
+	if (ret != USBG_SUCCESS)
+		goto out;
+
+	ret = usbg_write_string(f->path, f->name, "ifname", attrs->ifname);
+	if (ret != USBG_SUCCESS)
+		goto out;
+
+	ret = usbg_write_dec(f->path, f->name, "qmult", attrs->qmult);
+
+out:
+	return ret;
+}
+
+int  usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs)
+{
+	int ret = USBG_ERROR_INVALID_PARAM;
+
 	if (!f || !f_attrs)
-		return;
+		return USBG_ERROR_INVALID_PARAM;
 
 	switch (f->type) {
 	case F_SERIAL:
 	case F_ACM:
 	case F_OBEX:
-		usbg_write_dec(f->path, f->name, "port_num", f_attrs->serial.port_num);
+		ret = usbg_write_dec(f->path, f->name, "port_num", f_attrs->serial.port_num);
 		break;
 	case F_ECM:
 	case F_SUBSET:
 	case F_NCM:
 	case F_EEM:
 	case F_RNDIS:
-		addr = ether_ntoa(&f_attrs->net.dev_addr);
-		usbg_write_string(f->path, f->name, "dev_addr", addr);
-
-		addr = ether_ntoa(&f_attrs->net.host_addr);
-		usbg_write_string(f->path, f->name, "host_addr", addr);
-
-		usbg_write_string(f->path, f->name, "ifname", f_attrs->net.ifname);
-
-		usbg_write_dec(f->path, f->name, "qmult", f_attrs->net.qmult);
+		ret = usbg_set_function_net_attrs(f, &f_attrs->net);
 		break;
 	case F_PHONET:
-		usbg_write_string(f->path, f->name, "ifname", f_attrs->phonet.ifname);
+		ret = usbg_write_string(f->path, f->name, "ifname", f_attrs->phonet.ifname);
 		break;
 	default:
 		ERROR("Unsupported function type\n");
 	}
+
+	return ret;
 }
 
-void usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *dev_addr)
+int usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *dev_addr)
 {
-	char *str_addr;
+	int ret = USBG_SUCCESS;
+
+	if (f && dev_addr) {
+		char *str_addr = ether_ntoa(dev_addr);
+		ret = usbg_write_string(f->path, f->name, "dev_addr", str_addr);
+	} else {
+		ret = USBG_ERROR_INVALID_PARAM;
+	}
 
-	str_addr = ether_ntoa(dev_addr);
-	usbg_write_string(f->path, f->name, "dev_addr", str_addr);
+	return ret;
 }
 
-void usbg_set_net_host_addr(usbg_function *f, struct ether_addr *host_addr)
+int usbg_set_net_host_addr(usbg_function *f, struct ether_addr *host_addr)
 {
-	char *str_addr;
+	int ret = USBG_SUCCESS;
 
-	str_addr = ether_ntoa(host_addr);
-	usbg_write_string(f->path, f->name, "host_addr", str_addr);
+	if (f && host_addr) {
+		char *str_addr = ether_ntoa(host_addr);
+		ret = usbg_write_string(f->path, f->name, "host_addr", str_addr);
+	} else {
+		ret = USBG_ERROR_INVALID_PARAM;
+	}
+
+	return ret;
 }
 
-void usbg_set_net_qmult(usbg_function *f, int qmult)
+int usbg_set_net_qmult(usbg_function *f, int qmult)
 {
-	usbg_write_dec(f->path, f->name, "qmult", qmult);
+	return f ? usbg_write_dec(f->path, f->name, "qmult", qmult)
+			: USBG_ERROR_INVALID_PARAM;
 }
 
 usbg_gadget *usbg_get_first_gadget(usbg_state *s)
-- 
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