From 7652b678824a2edc6924c333ae4f2ed54ceae640 Mon Sep 17 00:00:00 2001 From: Frank Benkert Date: Thu, 1 Jun 2017 15:19:40 -0600 Subject: [PATCH 1/7] Update to apps/system/compsite assocated with big changes to the composite device logic --- system/composite/README.txt | 63 +++++++++++++++++++++---------- system/composite/composite_main.c | 10 +++-- 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/system/composite/README.txt b/system/composite/README.txt index 58922cba7..fe7be25e4 100755 --- a/system/composite/README.txt +++ b/system/composite/README.txt @@ -1,33 +1,58 @@ system/composite ^^^^^^^^^^^^^^^^^^ - This logic adds a NXH command to control a USB composite device. The only - supported composite is CDC/ACM serial with a USB mass storage device. + This logic adds a NSH command to control a USB composite device. The only + supported devices in the composite are CDC/ACM serial and a USB mass storage + device. Which devices are enclosed in a composite device is configured with + an array of configuration-structs, handed over to the function + composite_initialize(). Required overall configuration: - CONFIG_USBDEV=y - USB device support - CONFIG_USBDEV_COMPOSITE=y - USB composite device support - CONFIG_COMPOSITE_IAD=y - Interface associate descriptor needed + Enable the USB Support of your Hardware / Processor e.g. SAMV7_USBDEVHS=y - CONFIG_CDCACM=y - USB CDC/ACM serial device support - CONFIG_CDCACM_COMPOSITE=y - USB CDC/ACM serial composite device support - CONFIG_CDCACM_IFNOBASE=0 - CDC/ACM interfaces start with number 0 - CONFIG_CDCACM_STRBASE=4 - Base of string numbers (not really needed) - CONFIG_CDCACM_EPINTIN=1 - Endpoint numbers must be unique - CONFIG_CDCACM_EPBULKIN=2 - CONFIG_CDCACM_EPBULKOUT=3 + CONFIG_USBDEV=y - USB device support + CONFIG_USBDEV_COMPOSITE=y - USB composite device support + CONFIG_COMPOSITE_IAD=y - Interface associate descriptor needed - CONFIG_USBMSC - USB mass storage device support - CONFIG_USBMSC_COMPOSITE=y - USB mass storage composite device support - CONFIG_USBMSC_IFNOBASE=2 - USB mass storage interfaces start with number 2 - CONFIG_USBMSC_STRBASE=4 - Base of string numbers (needed) - CONFIG_USBMSC_EPBULKOUT=4 - Endpoint numbers must be unique - CONFIG_USBMSC_EPBULKIN=5 + CONFIG_CDCACM=y - USB CDC/ACM serial device support + CONFIG_CDCACM_COMPOSITE=y - USB CDC/ACM serial composite device support + + The interface-, string-descriptor- and endpoint-numbers are configured via the + configuration-structs as noted above. The CDC/ACM serial device needs three + endpoints; one interrupt-driven and two bulk endpoints. + + CONFIG_USBMSC=y - USB mass storage device support + CONFIG_USBMSC_COMPOSITE=y - USB mass storage composite device support + + Like the configuration for the CDC/ACM, the descriptor- and endpoint-numbers + are configured via the configuration struct. + + Depending on the configuration struct you need to configure different vendor- + and product-IDs. Each VID/PID is unique to a device and thus to a dedicated + configuration. + + Linux tries to detect the device types and installs default drivers if the + VID/PID pair is unknown. + + Windows insists on a known and installed configuration. With an Atmel + hardware and Atmel-Studio or the Atmel-USB-drivers installed, you can test + your configuration with Atmel Example Vendor- and Product-IDs. + + If you have a USBMSC and a CDC/ACM configured in your combo, then you can try + to use + + - VID = 0x03EB (ATMEL) + - PID = 0x2424 (ASF Example with MSC and CDC) + + If for example you try to test a configuration with up to seven CDCs, then + + - VID = 0x03EB (ATMEL) + - PID = 0x2426 (ASF Example with up to seven CDCs) CONFIG_NSH_BUILTIN_APPS This add-on can be built as two NSH "built-in" commands if this option - is selected: 'conn' will connect the USB composite device; 'msdis' + is selected: 'conn' will connect the USB composite device; 'disconn' will disconnect the USB composite device. Configuration options unique to this add-on: diff --git a/system/composite/composite_main.c b/system/composite/composite_main.c index ab473124b..45f9be1db 100644 --- a/system/composite/composite_main.c +++ b/system/composite/composite_main.c @@ -549,7 +549,8 @@ static void usbmsc_disconnect(void) * ****************************************************************************/ -int board_mscclassobject(FAR struct usbdevclass_driver_s **classdev) +int board_mscclassobject(int minor, FAR struct usbdev_description_s *devdesc, + FAR struct usbdevclass_driver_s **classdev) { int ret; @@ -620,7 +621,7 @@ int board_mscclassobject(FAR struct usbdevclass_driver_s **classdev) /* Get the mass storage device's class object */ - ret = usbmsc_classobject(g_composite.mschandle, classdev); + ret = usbmsc_classobject(g_composite.mschandle, devdesc, classdev); if (ret < 0) { printf("board_mscclassobject: usbmsc_classobject failed: %d\n", -ret); @@ -672,14 +673,15 @@ void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev) * ****************************************************************************/ -int board_cdcclassobject(FAR struct usbdevclass_driver_s **classdev) +int board_cdcclassobject(int minor, FAR struct usbdev_description_s *devdesc, + FAR struct usbdevclass_driver_s **classdev) { int ret; /* Initialize the USB serial driver */ printf("board_cdcclassobject: Initializing USB serial driver\n"); - ret = cdcacm_classobject(CONFIG_SYSTEM_COMPOSITE_TTYUSB, classdev); + ret = cdcacm_classobject(minor, devdesc, classdev); if (ret < 0) { printf("board_cdcclassobject: ERROR: Failed to create the USB serial device: %d\n", -ret); From 95eb20343b8ee856cf174157322797123cfeb573 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 2 Jun 2017 07:09:44 -0600 Subject: [PATCH 2/7] apps/system/composite: Add a configuration option to the boardctl() calls to support multiple composite device configurations dynamically. --- system/composite/composite_main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/system/composite/composite_main.c b/system/composite/composite_main.c index 45f9be1db..044a402df 100644 --- a/system/composite/composite_main.c +++ b/system/composite/composite_main.c @@ -517,6 +517,7 @@ static void usbmsc_disconnect(void) ctrl.usbdev = BOARDIOC_USBDEV_MSC; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; ctrl.instance = 0; + ctrl.config = 0; ctrl.handle = &g_composite.mschandle; (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -716,6 +717,7 @@ void board_cdcuninitialize(FAR struct usbdevclass_driver_s *classdev) ctrl.usbdev = BOARDIOC_USBDEV_CDCACM; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; ctrl.instance = CONFIG_SYSTEM_COMPOSITE_TTYUSB; + ctrl.config = 0; ctrl.handle = (FAR void **)&classdev; (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -774,6 +776,7 @@ int conn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_INITIALIZE; ctrl.instance = 0; + ctrl.config = 0; ctrl.handle = NULL; ret = boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -790,6 +793,7 @@ int conn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_CONNECT; ctrl.instance = 0; + ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; ret = boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -894,6 +898,7 @@ errout: ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; ctrl.instance = 0; + ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -936,6 +941,7 @@ int disconn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; ctrl.instance = 0; + ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); From 23f1dd5e48b2e4eb6629f6e99a7de014627cdf89 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 15 Jul 2017 08:58:14 -0600 Subject: [PATCH 3/7] system/composite: Remove CDC/ACM and MSC configuration logic. This belongs in the OS composite initialization. Add and argument so that you can select the USB composite configuration to be attached. --- system/composite/composite_main.c | 281 +++++------------------------- 1 file changed, 42 insertions(+), 239 deletions(-) diff --git a/system/composite/composite_main.c b/system/composite/composite_main.c index dfe69161b..f685b3b6c 100644 --- a/system/composite/composite_main.c +++ b/system/composite/composite_main.c @@ -1,7 +1,7 @@ /**************************************************************************** * system/composite/composite_main.c * - * Copyright (C) 2012-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2012-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -404,7 +404,7 @@ static int open_serial(void) if (g_composite.outfd < 0) { errcode = errno; - printf("open_serial: ERROR: Failed to open %s for writing: %d\n", + fprintf(stderr, "open_serial: ERROR: Failed to open %s for writing: %d\n", CONFIG_SYSTEM_COMPOSITE_SERDEV, errcode); /* ENOTCONN means that the USB device is not yet connected */ @@ -443,7 +443,7 @@ static int open_serial(void) if (g_composite.infd < 0) { errcode = errno; - printf("open_serial: ERROR: Failed to open%s for reading: %d\n", + fprintf(stderr, "open_serial: ERROR: Failed to open%s for reading: %d\n", CONFIG_SYSTEM_COMPOSITE_SERDEV, errcode); close(g_composite.outfd); return -errcode; @@ -471,7 +471,7 @@ static int echo_serial(void) errcode = errno; if (errcode != EAGAIN) { - printf("echo_serial: ERROR: read failed: %d\n", errcode); + fprintf(stderr, "echo_serial: ERROR: read failed: %d\n", errcode); return -errcode; } return OK; @@ -483,12 +483,12 @@ static int echo_serial(void) if (byteswritten < 0) { errcode = errno; - printf("echo_serial: ERROR: write failed: %d\n", errcode); + fprintf(stderr, "echo_serial: ERROR: write failed: %d\n", errcode); return -errcode; } else if (byteswritten != bytesread) { - printf("echo_serial: ERROR: read size: %d write size: %d\n", + fprintf(stderr, "echo_serial: ERROR: read size: %d write size: %d\n", bytesread, byteswritten); } @@ -496,233 +496,10 @@ static int echo_serial(void) } #endif -/**************************************************************************** - * Name: usbmsc_disconnect - * - * Description: - * Disconnect the USB MSC device - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -static void usbmsc_disconnect(void) -{ - struct boardioc_usbdev_ctrl_s ctrl; - - ctrl.usbdev = BOARDIOC_USBDEV_MSC; - ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = 0; - ctrl.config = 0; - ctrl.handle = &g_composite.mschandle; - - (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); -} - /**************************************************************************** * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: board_mscclassobject - * - * Description: - * If the mass storage class driver is part of composite device, then - * its instantiation and configuration is a multi-step, board-specific, - * process (See comments for usbmsc_configure below). In this case, - * board-specific logic must provide board_mscclassobject(). - * - * board_mscclassobject() is called from the composite driver. It must - * encapsulate the instantiation and configuration of the mass storage - * class and the return the mass storage device's class driver instance - * to the composite driver. - * - * Input Parameters: - * classdev - The location to return the mass storage class' device - * instance. - * - * Returned Value: - * 0 on success; a negated errno on failure - * - ****************************************************************************/ - -int board_mscclassobject(int minor, FAR struct usbdev_description_s *devdesc, - FAR struct usbdevclass_driver_s **classdev) -{ - int ret; - - DEBUGASSERT(g_composite.mschandle == NULL); - - /* Initialize USB trace output IDs */ - - usbtrace_enable(TRACE_BITSET); - check_test_memory_usage("After usbtrace_enable()"); - - /* Configure the mass storage device */ - - printf("board_mscclassobject: Configuring with NLUNS=%d\n", CONFIG_SYSTEM_COMPOSITE_NLUNS); - ret = usbmsc_configure(CONFIG_SYSTEM_COMPOSITE_NLUNS, &g_composite.mschandle); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_configure failed: %d\n", -ret); - return ret; - } - - printf("board_mscclassobject: MSC handle=%p\n", g_composite.mschandle); - check_test_memory_usage("After usbmsc_configure()"); - - /* Bind the LUN(s) */ - - printf("board_mscclassobject: Bind LUN=0 to %s\n", CONFIG_SYSTEM_COMPOSITE_DEVPATH1); - ret = usbmsc_bindlun(g_composite.mschandle, CONFIG_SYSTEM_COMPOSITE_DEVPATH1, 0, 0, 0, false); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_bindlun failed for LUN 1 using %s: %d\n", - CONFIG_SYSTEM_COMPOSITE_DEVPATH1, -ret); - usbmsc_disconnect(); - return ret; - } - - check_test_memory_usage("After usbmsc_bindlun()"); - -#if CONFIG_SYSTEM_COMPOSITE_NLUNS > 1 - - printf("board_mscclassobject: Bind LUN=1 to %s\n", CONFIG_SYSTEM_COMPOSITE_DEVPATH2); - ret = usbmsc_bindlun(g_composite.mschandle, CONFIG_SYSTEM_COMPOSITE_DEVPATH2, 1, 0, 0, false); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_bindlun failed for LUN 2 using %s: %d\n", - CONFIG_SYSTEM_COMPOSITE_DEVPATH2, -ret); - usbmsc_disconnect(); - return ret; - } - - check_test_memory_usage("After usbmsc_bindlun() #2"); - -#if CONFIG_SYSTEM_COMPOSITE_NLUNS > 2 - - printf("board_mscclassobject: Bind LUN=2 to %s\n", CONFIG_SYSTEM_COMPOSITE_DEVPATH3); - ret = usbmsc_bindlun(g_composite.mschandle, CONFIG_SYSTEM_COMPOSITE_DEVPATH3, 2, 0, 0, false); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_bindlun failed for LUN 3 using %s: %d\n", - CONFIG_SYSTEM_COMPOSITE_DEVPATH3, -ret); - usbmsc_disconnect(); - return ret; - } - - check_test_memory_usage("After usbmsc_bindlun() #3"); - -#endif -#endif - - /* Get the mass storage device's class object */ - - ret = usbmsc_classobject(g_composite.mschandle, devdesc, classdev); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_classobject failed: %d\n", -ret); - usbmsc_disconnect(); - } - - check_test_memory_usage("After usbmsc_classobject()"); - return ret; -} - -/**************************************************************************** - * Name: board_mscuninitialize - * - * Description: - * Un-initialize the USB storage class driver. This is just an application- - * specific wrapper aboutn usbmsc_unitialize() that is called form the composite - * device logic. - * - * Input Parameters: - * classdev - The class driver instrance previously give to the composite - * driver by board_mscclassobject(). - * - * Returned Value: - * None - * - ****************************************************************************/ - -void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev) -{ - DEBUGASSERT(g_composite.mschandle != NULL); - usbmsc_disconnect(); -} - -/**************************************************************************** - * Name: board_cdcclassobject - * - * Description: - * If the CDC serial class driver is part of composite device, then - * board-specific logic must provide board_cdcclassobject(). In the simplest - * case, board_cdcclassobject() is simply a wrapper around cdcacm_classobject() - * that provides the correct device minor number. - * - * Input Parameters: - * classdev - The location to return the CDC serial class' device - * instance. - * - * Returned Value: - * 0 on success; a negated errno on failure - * - ****************************************************************************/ - -int board_cdcclassobject(int minor, FAR struct usbdev_description_s *devdesc, - FAR struct usbdevclass_driver_s **classdev) -{ - int ret; - - /* Initialize the USB serial driver */ - - printf("board_cdcclassobject: Initializing USB serial driver\n"); - ret = cdcacm_classobject(minor, devdesc, classdev); - if (ret < 0) - { - printf("board_cdcclassobject: ERROR: Failed to create the USB serial device: %d\n", -ret); - } - - return ret; -} - -/**************************************************************************** - * Name: board_cdcuninitialize - * - * Description: - * Un-initialize the USB serial class driver. This is just an application- - * specific wrapper aboutn cdcadm_unitialize() that is called form the composite - * device logic. - * - * Input Parameters: - * classdev - The class driver instrance previously give to the composite - * driver by board_cdcclassobject(). - * - * Returned Value: - * None - * - ****************************************************************************/ - -void board_cdcuninitialize(FAR struct usbdevclass_driver_s *classdev) -{ - struct boardioc_usbdev_ctrl_s ctrl; - - DEBUGASSERT(classdev != NULL); - - ctrl.usbdev = BOARDIOC_USBDEV_CDCACM; - ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = CONFIG_SYSTEM_COMPOSITE_TTYUSB; - ctrl.config = 0; - ctrl.handle = (FAR void **)&classdev; - - (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); -} - /**************************************************************************** * conn_main * @@ -741,6 +518,7 @@ int conn_main(int argc, char *argv[]) #endif { struct boardioc_usbdev_ctrl_s ctrl; + int instance = 0; int ret; /* If this program is implemented as the NSH 'conn' command, then we need to @@ -752,13 +530,25 @@ int conn_main(int argc, char *argv[]) * USB mass storage device is already configured). */ - if (g_composite.cmphandle) - { - printf("conn_main: ERROR: Already connected\n"); - return 1; - } + if (g_composite.cmphandle) + { + fprintf(stderr, "conn_main: ERROR: Already connected\n"); + return 1; + } #endif + /* There is one optional argument.. the interface instance number */ + + if (argc == 2) + { + instance = atoi(argv[1]); + } + else if (argc > 2) + { + fprintf(stderr, "conn_main: ERROR: Too many arguments: %d\n", argc); + return EXIT_FAILURE; + } + #ifdef CONFIG_SYSTEM_COMPOSITE_DEBUGMM # ifdef CONFIG_CAN_PASS_STRUCTS g_composite.mmstart = mallinfo(); @@ -775,7 +565,7 @@ int conn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_INITIALIZE; - ctrl.instance = 0; + ctrl.instance = instance; ctrl.config = 0; ctrl.handle = NULL; @@ -792,7 +582,7 @@ int conn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_CONNECT; - ctrl.instance = 0; + ctrl.instance = instance; ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; @@ -897,7 +687,7 @@ errout: ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = 0; + ctrl.instance = instance; ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; @@ -925,22 +715,35 @@ int disconn_main(int argc, char *argv[]) #endif { struct boardioc_usbdev_ctrl_s ctrl; + int instance = instance; /* First check if the USB mass storage device is already connected */ if (!g_composite.cmphandle) { - printf("disconn_main: ERROR: Not connected\n"); + fprintf(stderr, "disconn_main: ERROR: Not connected\n"); return 1; } check_test_memory_usage("Since MS connection"); + /* There is one optional argument.. the interface instance number */ + + if (argc == 2) + { + instance = atoi(argv[1]); + } + else if (argc > 2) + { + fprintf(stderr, "conn_main: ERROR: Too many arguments: %d\n", argc); + return EXIT_FAILURE; + } + /* Then disconnect the device and uninitialize the USB mass storage driver */ ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = 0; + ctrl.instance = instance; ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; From 668179495f0e5204ba51108ccbe7aad71a960367 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 15 Jul 2017 09:26:49 -0600 Subject: [PATCH 4/7] apps/system/composite: Restore USB tracing; remove unused field in a structure. --- system/composite/composite.h | 1 - system/composite/composite_main.c | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/system/composite/composite.h b/system/composite/composite.h index 56ec20cd7..338bc65d4 100644 --- a/system/composite/composite.h +++ b/system/composite/composite.h @@ -186,7 +186,6 @@ struct composite_state_s */ FAR void *cmphandle; /* Composite device handle */ - FAR void *mschandle; /* Mass storage device handle */ /* Serial file descriptors */ diff --git a/system/composite/composite_main.c b/system/composite/composite_main.c index f685b3b6c..a3a55ef2f 100644 --- a/system/composite/composite_main.c +++ b/system/composite/composite_main.c @@ -549,6 +549,10 @@ int conn_main(int argc, char *argv[]) return EXIT_FAILURE; } + /* Initialize USB trace output IDs */ + + usbtrace_enable(TRACE_BITSET); + #ifdef CONFIG_SYSTEM_COMPOSITE_DEBUGMM # ifdef CONFIG_CAN_PASS_STRUCTS g_composite.mmstart = mallinfo(); From 99b41a291b78da39d530381db1aab688ef2469e0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 15 Jul 2017 11:04:13 -0600 Subject: [PATCH 5/7] apps/system/composite: Remove configuration settings that are no longer used. --- system/composite/Kconfig | 64 ---------------------------------------- 1 file changed, 64 deletions(-) diff --git a/system/composite/Kconfig b/system/composite/Kconfig index 108ed9b9e..5da58a488 100644 --- a/system/composite/Kconfig +++ b/system/composite/Kconfig @@ -15,72 +15,8 @@ menuconfig SYSTEM_COMPOSITE disconn: Disconnect the mass storage device to the host if SYSTEM_COMPOSITE -if USBMSC_COMPOSITE - -config SYSTEM_COMPOSITE_NLUNS - int "Number of LUNs" - default 1 - ---help--- - Defines the number of logical units (LUNs) exported by the USB - storage driver. Each LUN corresponds to one exported block driver - (or partition of a block driver). May be 1, 2, or 3. Default is 1. - -config SYSTEM_COMPOSITE_DEVMINOR1 - int "LUN1 Minor Device Number" - default 0 - ---help--- - The minor device number of the block driver for the first LUN. For - example, N in /dev/mmcsdN. Used for registering the block driver. - Default is zero. - -config SYSTEM_COMPOSITE_DEVPATH1 - string "LUN1 Device Path" - default "/dev/mmcsd0" - ---help--- - The full path to the registered block driver. Default is - "/dev/mmcsd0" - -config SYSTEM_COMPOSITE_DEVMINOR2 - int "LUN2 Minor Device Number" - default 1 - ---help--- - The minor device number of the block driver for the second LUN. For - example, N in /dev/mmcsdN. Used for registering the block driver. - Ignored if SYSTEM_COMPOSITE_NLUNS < 2. Default is one. - -config SYSTEM_COMPOSITE_DEVPATH2 - string "LUN2 Device Path" - default "/dev/mmcsd1" - ---help--- - The full path to the registered block driver. Ignored if - SYSTEM_COMPOSITE_NLUNS < 2. Default is "/dev/mmcsd1" - -config SYSTEM_COMPOSITE_DEVMINOR3 - int "LUN3 Minor Device Number" - default 2 - ---help--- - The minor device number of the block driver for the third LUN. For - example, N in /dev/mmcsdN. Used for registering the block driver. - Ignored if SYSTEM_COMPOSITE_NLUNS < 2. Default is two. - -config SYSTEM_COMPOSITE_DEVPATH3 - string "LUN3 Device Path" - default "/dev/mmcsd2" - ---help--- - The full path to the registered block driver. Ignored if - SYSTEM_COMPOSITE_NLUNS < 2. Default is "/dev/mmcsd2" - -endif # USBMSC_COMPOSITE - if CDCACM_COMPOSITE -config SYSTEM_COMPOSITE_TTYUSB - int "USB serial device minor number" - default 0 - ---help--- - The minor number of the USB serial device. Default is zero - (corresponding to /dev/ttyUSB0 or /dev/ttyACM0). - config SYSTEM_COMPOSITE_SERDEV string "USB serial device path" default "/dev/ttyACM0" From c7f854016919606911ed19b5ab3c36d0e95722e6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 15 Jul 2017 12:13:17 -0600 Subject: [PATCH 6/7] apps/system/composite: Fix configuration selecting.. was setting the port number, not the configure ID. Also add a configuration option to select the default configuration. --- system/composite/Kconfig | 9 +++++++++ system/composite/composite_main.c | 26 +++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/system/composite/Kconfig b/system/composite/Kconfig index 5da58a488..a4f0b6b4c 100644 --- a/system/composite/Kconfig +++ b/system/composite/Kconfig @@ -15,6 +15,15 @@ menuconfig SYSTEM_COMPOSITE disconn: Disconnect the mass storage device to the host if SYSTEM_COMPOSITE + +config SYSTEM_COMPOSITE_DEFCONFIG + int "Default composite configuration" + default 0 + ---help--- + Boards may support multiple composite configurations. If so, then + this is the default configuration that the conn command will use if + no configuration ID is provided on the command line. + if CDCACM_COMPOSITE config SYSTEM_COMPOSITE_SERDEV diff --git a/system/composite/composite_main.c b/system/composite/composite_main.c index a3a55ef2f..43cf0d6b5 100644 --- a/system/composite/composite_main.c +++ b/system/composite/composite_main.c @@ -518,7 +518,7 @@ int conn_main(int argc, char *argv[]) #endif { struct boardioc_usbdev_ctrl_s ctrl; - int instance = 0; + int config = CONFIG_SYSTEM_COMPOSITE_DEFCONFIG; int ret; /* If this program is implemented as the NSH 'conn' command, then we need to @@ -537,11 +537,11 @@ int conn_main(int argc, char *argv[]) } #endif - /* There is one optional argument.. the interface instance number */ + /* There is one optional argument.. the interface configuration ID */ if (argc == 2) { - instance = atoi(argv[1]); + config = atoi(argv[1]); } else if (argc > 2) { @@ -569,8 +569,8 @@ int conn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_INITIALIZE; - ctrl.instance = instance; - ctrl.config = 0; + ctrl.instance = 0; + ctrl.config = config; ctrl.handle = NULL; ret = boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -586,8 +586,8 @@ int conn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_CONNECT; - ctrl.instance = instance; - ctrl.config = 0; + ctrl.instance = 0; + ctrl.config = config; ctrl.handle = &g_composite.cmphandle; ret = boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -691,8 +691,8 @@ errout: ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = instance; - ctrl.config = 0; + ctrl.instance = 0; + ctrl.config = config; ctrl.handle = &g_composite.cmphandle; (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -719,7 +719,7 @@ int disconn_main(int argc, char *argv[]) #endif { struct boardioc_usbdev_ctrl_s ctrl; - int instance = instance; + int config = CONFIG_SYSTEM_COMPOSITE_DEFCONFIG; /* First check if the USB mass storage device is already connected */ @@ -731,7 +731,7 @@ int disconn_main(int argc, char *argv[]) check_test_memory_usage("Since MS connection"); - /* There is one optional argument.. the interface instance number */ + /* There is one optional argument.. the interface configuration ID */ if (argc == 2) { @@ -747,8 +747,8 @@ int disconn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = instance; - ctrl.config = 0; + ctrl.instance = 0; + ctrl.config = config; ctrl.handle = &g_composite.cmphandle; (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); From 7b9ec306db6e95f368387eeeec8c8df0f0c2f748 Mon Sep 17 00:00:00 2001 From: Frank Benkert Date: Sun, 16 Jul 2017 08:45:26 -0600 Subject: [PATCH 7/7] Squashed commit of the following: commit 99b41a291b78da39d530381db1aab688ef2469e0 Author: Gregory Nutt Date: Sat Jul 15 11:04:13 2017 -0600 apps/system/composite: Remove configuration settings that are no longer used. commit 668179495f0e5204ba51108ccbe7aad71a960367 Author: Gregory Nutt Date: Sat Jul 15 09:26:49 2017 -0600 apps/system/composite: Restore USB tracing; remove unused field in a structure. commit 23f1dd5e48b2e4eb6629f6e99a7de014627cdf89 Author: Gregory Nutt Date: Sat Jul 15 08:58:14 2017 -0600 system/composite: Remove CDC/ACM and MSC configuration logic. This belongs in the OS composite initialization. Add and argument so that you can select the USB composite configuration to be attached. commit f8711488f1eaeca777407fe09fb2967331f7f211 Merge: 00896040 234afcd8 Author: Gregory Nutt Date: Fri Jul 14 16:25:48 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit 00896040441da1b187d0b39cb2a9e3c393b28865 Merge: f913ea01 ae1eeada Author: Gregory Nutt Date: Thu Jul 13 13:59:25 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit f913ea0179da7a387414145b27d77524c6cbee88 Merge: bcbdd798 915b42f8 Author: Gregory Nutt Date: Mon Jul 10 11:08:46 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit bcbdd798c60bb24fe03b884e32b892ce805cb093 Merge: 2219c02d 1657d1ff Author: Gregory Nutt Date: Fri Jul 7 20:28:30 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit 2219c02ddb89c65e5257f681b73da5d6acc1513b Merge: fe1e52a8 d81d9c41 Author: Gregory Nutt Date: Wed Jul 5 11:12:09 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit fe1e52a83a4a419671b388ada7ed2c79d20604d4 Merge: 94f82d47 75f29d9d Author: Gregory Nutt Date: Fri Jun 30 16:14:36 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit 94f82d473dc78157a38490edcc7ede010e106394 Merge: a11806ee ffe0640d Author: Gregory Nutt Date: Thu Jun 29 10:19:55 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit a11806ee5f45dd0534d00c85950ef2812098ead7 Merge: f29dc985 5f5f8878 Author: Gregory Nutt Date: Mon Jun 26 11:57:00 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit f29dc98512c8945d839aaebacbf4a27205b988e4 Merge: 70faf0d1 d8759ffe Author: Gregory Nutt Date: Mon Jun 19 17:26:00 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit 70faf0d17066f91dc53200bafcdf3ece41737db2 Merge: 7d3b1581 a7770590 Author: Gregory Nutt Date: Fri Jun 16 17:33:46 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit 7d3b1581427fae75d84348ccfc116f7669fc76af Merge: b2c392d4 c8ae5f16 Author: Gregory Nutt Date: Fri Jun 16 17:30:39 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit b2c392d4fe1d9f630e018d750319d1d9707c3b8a Merge: 95eb2034 f3dc5bea Author: Gregory Nutt Date: Mon Jun 5 17:41:02 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit 95eb20343b8ee856cf174157322797123cfeb573 Author: Gregory Nutt Date: Fri Jun 2 07:09:44 2017 -0600 apps/system/composite: Add a configuration option to the boardctl() calls to support multiple composite device configurations dynamically. commit 7652b678824a2edc6924c333ae4f2ed54ceae640 Author: Frank Benkert Date: Thu Jun 1 15:19:40 2017 -0600 Update to apps/system/compsite assocated with big changes to the composite device logic --- system/composite/Kconfig | 64 ------- system/composite/README.txt | 63 +++++-- system/composite/composite.h | 1 - system/composite/composite_main.c | 285 ++++++------------------------ 4 files changed, 94 insertions(+), 319 deletions(-) diff --git a/system/composite/Kconfig b/system/composite/Kconfig index 108ed9b9e..5da58a488 100644 --- a/system/composite/Kconfig +++ b/system/composite/Kconfig @@ -15,72 +15,8 @@ menuconfig SYSTEM_COMPOSITE disconn: Disconnect the mass storage device to the host if SYSTEM_COMPOSITE -if USBMSC_COMPOSITE - -config SYSTEM_COMPOSITE_NLUNS - int "Number of LUNs" - default 1 - ---help--- - Defines the number of logical units (LUNs) exported by the USB - storage driver. Each LUN corresponds to one exported block driver - (or partition of a block driver). May be 1, 2, or 3. Default is 1. - -config SYSTEM_COMPOSITE_DEVMINOR1 - int "LUN1 Minor Device Number" - default 0 - ---help--- - The minor device number of the block driver for the first LUN. For - example, N in /dev/mmcsdN. Used for registering the block driver. - Default is zero. - -config SYSTEM_COMPOSITE_DEVPATH1 - string "LUN1 Device Path" - default "/dev/mmcsd0" - ---help--- - The full path to the registered block driver. Default is - "/dev/mmcsd0" - -config SYSTEM_COMPOSITE_DEVMINOR2 - int "LUN2 Minor Device Number" - default 1 - ---help--- - The minor device number of the block driver for the second LUN. For - example, N in /dev/mmcsdN. Used for registering the block driver. - Ignored if SYSTEM_COMPOSITE_NLUNS < 2. Default is one. - -config SYSTEM_COMPOSITE_DEVPATH2 - string "LUN2 Device Path" - default "/dev/mmcsd1" - ---help--- - The full path to the registered block driver. Ignored if - SYSTEM_COMPOSITE_NLUNS < 2. Default is "/dev/mmcsd1" - -config SYSTEM_COMPOSITE_DEVMINOR3 - int "LUN3 Minor Device Number" - default 2 - ---help--- - The minor device number of the block driver for the third LUN. For - example, N in /dev/mmcsdN. Used for registering the block driver. - Ignored if SYSTEM_COMPOSITE_NLUNS < 2. Default is two. - -config SYSTEM_COMPOSITE_DEVPATH3 - string "LUN3 Device Path" - default "/dev/mmcsd2" - ---help--- - The full path to the registered block driver. Ignored if - SYSTEM_COMPOSITE_NLUNS < 2. Default is "/dev/mmcsd2" - -endif # USBMSC_COMPOSITE - if CDCACM_COMPOSITE -config SYSTEM_COMPOSITE_TTYUSB - int "USB serial device minor number" - default 0 - ---help--- - The minor number of the USB serial device. Default is zero - (corresponding to /dev/ttyUSB0 or /dev/ttyACM0). - config SYSTEM_COMPOSITE_SERDEV string "USB serial device path" default "/dev/ttyACM0" diff --git a/system/composite/README.txt b/system/composite/README.txt index 58922cba7..fe7be25e4 100755 --- a/system/composite/README.txt +++ b/system/composite/README.txt @@ -1,33 +1,58 @@ system/composite ^^^^^^^^^^^^^^^^^^ - This logic adds a NXH command to control a USB composite device. The only - supported composite is CDC/ACM serial with a USB mass storage device. + This logic adds a NSH command to control a USB composite device. The only + supported devices in the composite are CDC/ACM serial and a USB mass storage + device. Which devices are enclosed in a composite device is configured with + an array of configuration-structs, handed over to the function + composite_initialize(). Required overall configuration: - CONFIG_USBDEV=y - USB device support - CONFIG_USBDEV_COMPOSITE=y - USB composite device support - CONFIG_COMPOSITE_IAD=y - Interface associate descriptor needed + Enable the USB Support of your Hardware / Processor e.g. SAMV7_USBDEVHS=y - CONFIG_CDCACM=y - USB CDC/ACM serial device support - CONFIG_CDCACM_COMPOSITE=y - USB CDC/ACM serial composite device support - CONFIG_CDCACM_IFNOBASE=0 - CDC/ACM interfaces start with number 0 - CONFIG_CDCACM_STRBASE=4 - Base of string numbers (not really needed) - CONFIG_CDCACM_EPINTIN=1 - Endpoint numbers must be unique - CONFIG_CDCACM_EPBULKIN=2 - CONFIG_CDCACM_EPBULKOUT=3 + CONFIG_USBDEV=y - USB device support + CONFIG_USBDEV_COMPOSITE=y - USB composite device support + CONFIG_COMPOSITE_IAD=y - Interface associate descriptor needed - CONFIG_USBMSC - USB mass storage device support - CONFIG_USBMSC_COMPOSITE=y - USB mass storage composite device support - CONFIG_USBMSC_IFNOBASE=2 - USB mass storage interfaces start with number 2 - CONFIG_USBMSC_STRBASE=4 - Base of string numbers (needed) - CONFIG_USBMSC_EPBULKOUT=4 - Endpoint numbers must be unique - CONFIG_USBMSC_EPBULKIN=5 + CONFIG_CDCACM=y - USB CDC/ACM serial device support + CONFIG_CDCACM_COMPOSITE=y - USB CDC/ACM serial composite device support + + The interface-, string-descriptor- and endpoint-numbers are configured via the + configuration-structs as noted above. The CDC/ACM serial device needs three + endpoints; one interrupt-driven and two bulk endpoints. + + CONFIG_USBMSC=y - USB mass storage device support + CONFIG_USBMSC_COMPOSITE=y - USB mass storage composite device support + + Like the configuration for the CDC/ACM, the descriptor- and endpoint-numbers + are configured via the configuration struct. + + Depending on the configuration struct you need to configure different vendor- + and product-IDs. Each VID/PID is unique to a device and thus to a dedicated + configuration. + + Linux tries to detect the device types and installs default drivers if the + VID/PID pair is unknown. + + Windows insists on a known and installed configuration. With an Atmel + hardware and Atmel-Studio or the Atmel-USB-drivers installed, you can test + your configuration with Atmel Example Vendor- and Product-IDs. + + If you have a USBMSC and a CDC/ACM configured in your combo, then you can try + to use + + - VID = 0x03EB (ATMEL) + - PID = 0x2424 (ASF Example with MSC and CDC) + + If for example you try to test a configuration with up to seven CDCs, then + + - VID = 0x03EB (ATMEL) + - PID = 0x2426 (ASF Example with up to seven CDCs) CONFIG_NSH_BUILTIN_APPS This add-on can be built as two NSH "built-in" commands if this option - is selected: 'conn' will connect the USB composite device; 'msdis' + is selected: 'conn' will connect the USB composite device; 'disconn' will disconnect the USB composite device. Configuration options unique to this add-on: diff --git a/system/composite/composite.h b/system/composite/composite.h index 56ec20cd7..338bc65d4 100644 --- a/system/composite/composite.h +++ b/system/composite/composite.h @@ -186,7 +186,6 @@ struct composite_state_s */ FAR void *cmphandle; /* Composite device handle */ - FAR void *mschandle; /* Mass storage device handle */ /* Serial file descriptors */ diff --git a/system/composite/composite_main.c b/system/composite/composite_main.c index 5a9bf25ea..a3a55ef2f 100644 --- a/system/composite/composite_main.c +++ b/system/composite/composite_main.c @@ -1,7 +1,7 @@ /**************************************************************************** * system/composite/composite_main.c * - * Copyright (C) 2012-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2012-2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -404,7 +404,7 @@ static int open_serial(void) if (g_composite.outfd < 0) { errcode = errno; - printf("open_serial: ERROR: Failed to open %s for writing: %d\n", + fprintf(stderr, "open_serial: ERROR: Failed to open %s for writing: %d\n", CONFIG_SYSTEM_COMPOSITE_SERDEV, errcode); /* ENOTCONN means that the USB device is not yet connected */ @@ -443,7 +443,7 @@ static int open_serial(void) if (g_composite.infd < 0) { errcode = errno; - printf("open_serial: ERROR: Failed to open%s for reading: %d\n", + fprintf(stderr, "open_serial: ERROR: Failed to open%s for reading: %d\n", CONFIG_SYSTEM_COMPOSITE_SERDEV, errcode); close(g_composite.outfd); return -errcode; @@ -471,7 +471,7 @@ static int echo_serial(void) errcode = errno; if (errcode != EAGAIN) { - printf("echo_serial: ERROR: read failed: %d\n", errcode); + fprintf(stderr, "echo_serial: ERROR: read failed: %d\n", errcode); return -errcode; } return OK; @@ -483,12 +483,12 @@ static int echo_serial(void) if (byteswritten < 0) { errcode = errno; - printf("echo_serial: ERROR: write failed: %d\n", errcode); + fprintf(stderr, "echo_serial: ERROR: write failed: %d\n", errcode); return -errcode; } else if (byteswritten != bytesread) { - printf("echo_serial: ERROR: read size: %d write size: %d\n", + fprintf(stderr, "echo_serial: ERROR: read size: %d write size: %d\n", bytesread, byteswritten); } @@ -496,229 +496,10 @@ static int echo_serial(void) } #endif -/**************************************************************************** - * Name: usbmsc_disconnect - * - * Description: - * Disconnect the USB MSC device - * - * Input Parameters: - * None - * - * Returned Value: - * None - * - ****************************************************************************/ - -static void usbmsc_disconnect(void) -{ - struct boardioc_usbdev_ctrl_s ctrl; - - ctrl.usbdev = BOARDIOC_USBDEV_MSC; - ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = 0; - ctrl.handle = &g_composite.mschandle; - - (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); -} - /**************************************************************************** * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: board_mscclassobject - * - * Description: - * If the mass storage class driver is part of composite device, then - * its instantiation and configuration is a multi-step, board-specific, - * process (See comments for usbmsc_configure below). In this case, - * board-specific logic must provide board_mscclassobject(). - * - * board_mscclassobject() is called from the composite driver. It must - * encapsulate the instantiation and configuration of the mass storage - * class and the return the mass storage device's class driver instance - * to the composite driver. - * - * Input Parameters: - * classdev - The location to return the mass storage class' device - * instance. - * - * Returned Value: - * 0 on success; a negated errno on failure - * - ****************************************************************************/ - -int board_mscclassobject(FAR struct usbdevclass_driver_s **classdev) -{ - int ret; - - DEBUGASSERT(g_composite.mschandle == NULL); - - /* Initialize USB trace output IDs */ - - usbtrace_enable(TRACE_BITSET); - check_test_memory_usage("After usbtrace_enable()"); - - /* Configure the mass storage device */ - - printf("board_mscclassobject: Configuring with NLUNS=%d\n", CONFIG_SYSTEM_COMPOSITE_NLUNS); - ret = usbmsc_configure(CONFIG_SYSTEM_COMPOSITE_NLUNS, &g_composite.mschandle); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_configure failed: %d\n", -ret); - return ret; - } - - printf("board_mscclassobject: MSC handle=%p\n", g_composite.mschandle); - check_test_memory_usage("After usbmsc_configure()"); - - /* Bind the LUN(s) */ - - printf("board_mscclassobject: Bind LUN=0 to %s\n", CONFIG_SYSTEM_COMPOSITE_DEVPATH1); - ret = usbmsc_bindlun(g_composite.mschandle, CONFIG_SYSTEM_COMPOSITE_DEVPATH1, 0, 0, 0, false); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_bindlun failed for LUN 1 using %s: %d\n", - CONFIG_SYSTEM_COMPOSITE_DEVPATH1, -ret); - usbmsc_disconnect(); - return ret; - } - - check_test_memory_usage("After usbmsc_bindlun()"); - -#if CONFIG_SYSTEM_COMPOSITE_NLUNS > 1 - - printf("board_mscclassobject: Bind LUN=1 to %s\n", CONFIG_SYSTEM_COMPOSITE_DEVPATH2); - ret = usbmsc_bindlun(g_composite.mschandle, CONFIG_SYSTEM_COMPOSITE_DEVPATH2, 1, 0, 0, false); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_bindlun failed for LUN 2 using %s: %d\n", - CONFIG_SYSTEM_COMPOSITE_DEVPATH2, -ret); - usbmsc_disconnect(); - return ret; - } - - check_test_memory_usage("After usbmsc_bindlun() #2"); - -#if CONFIG_SYSTEM_COMPOSITE_NLUNS > 2 - - printf("board_mscclassobject: Bind LUN=2 to %s\n", CONFIG_SYSTEM_COMPOSITE_DEVPATH3); - ret = usbmsc_bindlun(g_composite.mschandle, CONFIG_SYSTEM_COMPOSITE_DEVPATH3, 2, 0, 0, false); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_bindlun failed for LUN 3 using %s: %d\n", - CONFIG_SYSTEM_COMPOSITE_DEVPATH3, -ret); - usbmsc_disconnect(); - return ret; - } - - check_test_memory_usage("After usbmsc_bindlun() #3"); - -#endif -#endif - - /* Get the mass storage device's class object */ - - ret = usbmsc_classobject(g_composite.mschandle, classdev); - if (ret < 0) - { - printf("board_mscclassobject: usbmsc_classobject failed: %d\n", -ret); - usbmsc_disconnect(); - } - - check_test_memory_usage("After usbmsc_classobject()"); - return ret; -} - -/**************************************************************************** - * Name: board_mscuninitialize - * - * Description: - * Un-initialize the USB storage class driver. This is just an application- - * specific wrapper aboutn usbmsc_unitialize() that is called form the composite - * device logic. - * - * Input Parameters: - * classdev - The class driver instrance previously give to the composite - * driver by board_mscclassobject(). - * - * Returned Value: - * None - * - ****************************************************************************/ - -void board_mscuninitialize(FAR struct usbdevclass_driver_s *classdev) -{ - DEBUGASSERT(g_composite.mschandle != NULL); - usbmsc_disconnect(); -} - -/**************************************************************************** - * Name: board_cdcclassobject - * - * Description: - * If the CDC serial class driver is part of composite device, then - * board-specific logic must provide board_cdcclassobject(). In the simplest - * case, board_cdcclassobject() is simply a wrapper around cdcacm_classobject() - * that provides the correct device minor number. - * - * Input Parameters: - * classdev - The location to return the CDC serial class' device - * instance. - * - * Returned Value: - * 0 on success; a negated errno on failure - * - ****************************************************************************/ - -int board_cdcclassobject(FAR struct usbdevclass_driver_s **classdev) -{ - int ret; - - /* Initialize the USB serial driver */ - - printf("board_cdcclassobject: Initializing USB serial driver\n"); - ret = cdcacm_classobject(CONFIG_SYSTEM_COMPOSITE_TTYUSB, classdev); - if (ret < 0) - { - printf("board_cdcclassobject: ERROR: Failed to create the USB serial device: %d\n", -ret); - } - - return ret; -} - -/**************************************************************************** - * Name: board_cdcuninitialize - * - * Description: - * Un-initialize the USB serial class driver. This is just an application- - * specific wrapper aboutn cdcadm_unitialize() that is called form the composite - * device logic. - * - * Input Parameters: - * classdev - The class driver instrance previously give to the composite - * driver by board_cdcclassobject(). - * - * Returned Value: - * None - * - ****************************************************************************/ - -void board_cdcuninitialize(FAR struct usbdevclass_driver_s *classdev) -{ - struct boardioc_usbdev_ctrl_s ctrl; - - DEBUGASSERT(classdev != NULL); - - ctrl.usbdev = BOARDIOC_USBDEV_CDCACM; - ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = CONFIG_SYSTEM_COMPOSITE_TTYUSB; - ctrl.handle = (FAR void **)&classdev; - - (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); -} - /**************************************************************************** * conn_main * @@ -737,6 +518,7 @@ int conn_main(int argc, char *argv[]) #endif { struct boardioc_usbdev_ctrl_s ctrl; + int instance = 0; int ret; /* If this program is implemented as the NSH 'conn' command, then we need to @@ -748,13 +530,29 @@ int conn_main(int argc, char *argv[]) * USB mass storage device is already configured). */ - if (g_composite.cmphandle) - { - printf("conn_main: ERROR: Already connected\n"); - return 1; - } + if (g_composite.cmphandle) + { + fprintf(stderr, "conn_main: ERROR: Already connected\n"); + return 1; + } #endif + /* There is one optional argument.. the interface instance number */ + + if (argc == 2) + { + instance = atoi(argv[1]); + } + else if (argc > 2) + { + fprintf(stderr, "conn_main: ERROR: Too many arguments: %d\n", argc); + return EXIT_FAILURE; + } + + /* Initialize USB trace output IDs */ + + usbtrace_enable(TRACE_BITSET); + #ifdef CONFIG_SYSTEM_COMPOSITE_DEBUGMM # ifdef CONFIG_CAN_PASS_STRUCTS g_composite.mmstart = mallinfo(); @@ -771,7 +569,8 @@ int conn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_INITIALIZE; - ctrl.instance = 0; + ctrl.instance = instance; + ctrl.config = 0; ctrl.handle = NULL; ret = boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -787,7 +586,8 @@ int conn_main(int argc, char *argv[]) ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_CONNECT; - ctrl.instance = 0; + ctrl.instance = instance; + ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; ret = boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -891,7 +691,8 @@ errout: ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = 0; + ctrl.instance = instance; + ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl); @@ -918,22 +719,36 @@ int disconn_main(int argc, char *argv[]) #endif { struct boardioc_usbdev_ctrl_s ctrl; + int instance = instance; /* First check if the USB mass storage device is already connected */ if (!g_composite.cmphandle) { - printf("disconn_main: ERROR: Not connected\n"); + fprintf(stderr, "disconn_main: ERROR: Not connected\n"); return 1; } check_test_memory_usage("Since MS connection"); + /* There is one optional argument.. the interface instance number */ + + if (argc == 2) + { + instance = atoi(argv[1]); + } + else if (argc > 2) + { + fprintf(stderr, "conn_main: ERROR: Too many arguments: %d\n", argc); + return EXIT_FAILURE; + } + /* Then disconnect the device and uninitialize the USB mass storage driver */ ctrl.usbdev = BOARDIOC_USBDEV_COMPOSITE; ctrl.action = BOARDIOC_USBDEV_DISCONNECT; - ctrl.instance = 0; + ctrl.instance = instance; + ctrl.config = 0; ctrl.handle = &g_composite.cmphandle; (void)boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl);