Rename usbg_create_gadget() to usbg_create_vid_pid(). dd usbg_create_gadget() to allow gadget creation with given attributes and strings. Add usbg_set_gadget_attrs() which allow to set all attributes with one call. Add usbg_set_gadget_strs() which allow to set all strings with one call. Gadget structure creation and initialization has been moved to usbg_create_empty_gadget() to avoid copy-paste same code in usbg_create_gadget_vid_pid() and usbg_create_gadget(). Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> --- examples/gadget-acm-ecm.c | 2 +- include/usbg/usbg.h | 32 ++++++++++++- src/usbg.c | 117 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 136 insertions(+), 15 deletions(-) diff --git a/examples/gadget-acm-ecm.c b/examples/gadget-acm-ecm.c index e84c300..503a64f 100644 --- a/examples/gadget-acm-ecm.c +++ b/examples/gadget-acm-ecm.c @@ -42,7 +42,7 @@ int main(void) goto out1; } - g = usbg_create_gadget(s, "g1", VENDOR, PRODUCT); + g = usbg_create_gadget_vid_pid(s, "g1", VENDOR, PRODUCT); if (!g) { fprintf(stderr, "Error on create gadget\n"); goto out2; diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h index 2d832ba..c3e9d29 100644 --- a/include/usbg/usbg.h +++ b/include/usbg/usbg.h @@ -269,10 +269,31 @@ extern struct config *usbg_get_config(struct gadget *g, const char *name); * @param idProduct Gadget product ID * @return Pointer to gadget or NULL if the gadget cannot be created */ -extern struct gadget *usbg_create_gadget(struct state *s, char *name, +extern struct gadget *usbg_create_gadget_vid_pid(struct state *s, char *name, uint16_t idVendor, uint16_t idProduct); /** + * @brief Create a new USB gadget device and set given attributes + * and strings + * @param s Pointer to state + * @param name Name of the gadget + * @param g_attrs Gadget attributes to be set. If NULL setting is omitted. + * @param g_strs Gadget strings to be set. If NULL setting is omitted. + * @note Given strings are assumed to be in US English + * @return Pointer to gadget or NULL if the gadget cannot be created + */ +extern struct gadget *usbg_create_gadget(struct state *s, char *name, + struct gadget_attrs *g_attrs, struct gadget_strs *g_strs); + +/** + * @brief Set the USB gadget attributes + * @param g Pointer to gadget + * @param g_attrs Gadget attributes + */ +extern void usbg_set_gadget_attrs(struct gadget *g, + struct gadget_attrs *g_attrs); + +/** * @brief Set the USB gadget vendor id * @param g Pointer to gadget * @param idVendor USB device vendor id @@ -334,6 +355,15 @@ extern void usbg_set_gadget_device_bcd_device(struct gadget *g, extern void usbg_set_gadget_device_bcd_usb(struct gadget *g, uint16_t bcdUSB); /** + * @brief Set the USB gadget strings + * @param g Pointer to gadget + * @param lang USB language ID + * @param g_sttrs Gadget attributes + */ +extern void usbg_set_gadget_strs(struct gadget *g, int lang, + struct gadget_strs *g_strs); + +/** * @brief Set the serial number for a gadget * @param g Pointer to gadget * @param lang USB language ID diff --git a/src/usbg.c b/src/usbg.c index 543102c..8899a1e 100644 --- a/src/usbg.c +++ b/src/usbg.c @@ -525,22 +525,12 @@ struct binding *usbg_get_link_binding(struct config *c, struct function *f) return NULL; } -struct gadget *usbg_create_gadget(struct state *s, char *name, - uint16_t idVendor, uint16_t idProduct) +static struct gadget *usbg_create_empty_gadget(struct state *s, char *name) { char gpath[USBG_MAX_PATH_LENGTH]; - struct gadget *g, *cur; + struct gadget *g; int ret; - if (!s) - return NULL; - - g = usbg_get_gadget(s, name); - if (g) { - ERROR("duplicate gadget name\n"); - return NULL; - } - sprintf(gpath, "%s/%s", s->path, name); g = malloc(sizeof(struct gadget)); @@ -552,7 +542,7 @@ struct gadget *usbg_create_gadget(struct state *s, char *name, TAILQ_INIT(&g->configs); TAILQ_INIT(&g->functions); strcpy(g->name, name); - sprintf(g->path, "%s", s->path); + strcpy(g->path, s->path); g->parent = s; ret = mkdir(gpath, S_IRWXU|S_IRWXG|S_IRWXO); @@ -562,6 +552,34 @@ struct gadget *usbg_create_gadget(struct state *s, char *name, return NULL; } + /* Should be empty but read the default */ + usbg_read_string(g->path, g->name, "UDC", g->udc); + + return g; +} + + + +struct gadget *usbg_create_gadget_vid_pid(struct state *s, char *name, + uint16_t idVendor, uint16_t idProduct) +{ + struct gadget *g; + + if (!s) + return NULL; + + g = usbg_get_gadget(s, name); + if (g) { + ERROR("duplicate gadget name\n"); + return NULL; + } + + g = usbg_create_empty_gadget(s, name); + + if (!g) { + return NULL; + } + usbg_write_hex16(s->path, name, "idVendor", idVendor); usbg_write_hex16(s->path, name, "idProduct", idProduct); @@ -573,6 +591,60 @@ struct gadget *usbg_create_gadget(struct state *s, char *name, return g; } +struct gadget *usbg_create_gadget(struct state *s, char *name, + struct gadget_attrs *g_attrs, struct gadget_strs *g_strs) +{ + struct gadget *g; + + if (!s) + return NULL; + + g = usbg_get_gadget(s, name); + if (g) { + ERROR("duplicate gadget name\n"); + return NULL; + } + + g = usbg_create_empty_gadget(s, name); + + if (!g) { + return NULL; + } + + if (g_attrs) { + usbg_set_gadget_attrs(g, g_attrs); + } else { + usbg_parse_gadget_attrs(s->path, name, &g->attrs); + } + + if (g_strs) { + usbg_set_gadget_strs(g, LANG_US_ENG, g_strs); + } else { + usbg_parse_strings(s->path, name, &g->strs); + } + + INSERT_TAILQ_STRING_ORDER(&s->gadgets, ghead, name, g, gnode); + + return g; +} + +void usbg_set_gadget_attrs(struct gadget *g, struct gadget_attrs *g_attrs) +{ + if(!g || !g_attrs) { + return; + } + + g->attrs = *g_attrs; + usbg_write_hex16(g->path, g->name, "bcdUSB", g_attrs->bcdUSB); + usbg_write_hex8(g->path, g->name, "bDeviceClass", g_attrs->bDeviceClass); + usbg_write_hex8(g->path, g->name, "bDeviceSubClass", g_attrs->bDeviceSubClass); + usbg_write_hex8(g->path, g->name, "bDeviceProtocol", g_attrs->bDeviceProtocol); + usbg_write_hex8(g->path, g->name, "bMaxPacketSize0", g_attrs->bMaxPacketSize0); + usbg_write_hex16(g->path, g->name, "idVendor", g_attrs->idVendor); + usbg_write_hex16(g->path, g->name, "idProduct", g_attrs->idProduct); + usbg_write_hex16(g->path, g->name, "bcdDevice", g_attrs->bcdDevice); +} + void usbg_set_gadget_vendor_id(struct gadget *g, uint16_t idVendor) { g->attrs.idVendor = idVendor; @@ -621,6 +693,25 @@ void usbg_set_gadget_device_bcd_usb(struct gadget *g, uint16_t bcdUSB) usbg_write_hex16(g->path, g->name, "bcdUSB", bcdUSB); } +void usbg_set_gadget_strs(struct gadget *g, int lang, + struct gadget_strs *g_strs) +{ + char path[USBG_MAX_PATH_LENGTH]; + + sprintf(path, "%s/%s/%s/0x%x", g->path, g->name, STRINGS_DIR, lang); + + mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO); + + /* strings in library are hardcoded to US English for now */ + if (lang == LANG_US_ENG) { + g->strs = *g_strs; + } + + usbg_write_string(path, "", "serialnumber", g_strs->str_ser); + usbg_write_string(path, "", "manufacturer", g_strs->str_mnf); + usbg_write_string(path, "", "product", g_strs->str_prd); +} + void usbg_set_gadget_serial_number(struct gadget *g, int lang, char *serno) { char path[USBG_MAX_PATH_LENGTH]; -- 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