Skip to content

Commit

Permalink
system/usbmsc: Add support for setting paths bind to LUN at runtime
Browse files Browse the repository at this point in the history
Help

  nsh> msconn -h
  Usage: msconn [-o OPTION]... [-l LUNs]...
  Configures the USB mass storage device and exports the LUN(s).

  Supported arguments
    -o
        nc: No const LUN
        ro: Readonly
        rw: Read/Write(default)
    -l
        Device path to export

  Examples
    1. Export const LUN(s) only
        msconn
    2. Export /dev/ramx and const LUN(s)
        msconn -l /dev/ramx
    3. Export /dev/ramx without const LUN
        msconn -o nc -l /dev/ramx

Signed-off-by: wangjianyu3 <[email protected]>
  • Loading branch information
JianyuWang0623 committed Dec 2, 2024
1 parent 22d5d1d commit f8b23df
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 65 deletions.
9 changes: 8 additions & 1 deletion system/usbmsc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@ menuconfig SYSTEM_USBMSC
if SYSTEM_USBMSC

config SYSTEM_USBMSC_NLUNS
int "Number of LUNs"
int "Number of const 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_USBMSC_EXT_NLUNS
int "Number of max extra LUNs"
default 8
---help---
Defines the max number of logical units (LUNs) exported by the USB
storage driver at runtime.

config SYSTEM_USBMSC_DEVMINOR1
int "LUN1 Minor Device Number"
default 0
Expand Down
198 changes: 134 additions & 64 deletions system/usbmsc/usbmsc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <sys/types.h>
#include <sys/boardctl.h>

#include <fcntl.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
Expand Down Expand Up @@ -80,6 +81,23 @@
#define TRACE_BITSET (TRACE_INIT_BITS|TRACE_ERROR_BITS|TRACE_CLASS_BITS|\
TRACE_TRANSFER_BITS|TRACE_CONTROLLER_BITS|TRACE_INTERRUPT_BITS)

/* Save device path that will bind to a USB storage LUN later */

#define LUN_ADD_BIND(l, i, p, f) \
l[i].path = p; \
l[i].flags = f; \
i++;

/****************************************************************************
* Private Types
****************************************************************************/

struct usbmsc_lun_t
{
FAR const char *path; /* The full path to the block driver */
int flags; /* Access modes */
};

/****************************************************************************
* Private Data
****************************************************************************/
Expand Down Expand Up @@ -392,6 +410,26 @@ static void usbmsc_disconnect(FAR void *handle)
boardctl(BOARDIOC_USBDEV_CONTROL, (uintptr_t)&ctrl);
}

static void help_conn(void)
{
printf("Usage: msconn [-o OPTION]... [-l LUNs]...\n");
printf("Configures the USB mass storage device and exports the LUN(s).\n");
printf("\nSupported arguments\n");
printf(" -o\n");
printf(" nc: No const LUN\n");
printf(" ro: Readonly\n");
printf(" rw: Read/Write(default)\n");
printf(" -l\n");
printf(" Device path to export\n");
printf("\nExamples\n");
printf(" 1. Export const LUN(s) only\n");
printf(" msconn\n");
printf(" 2. Export /dev/ramx and const LUN(s)\n");
printf(" msconn -l /dev/ramx\n");
printf(" 3. Export /dev/ramx without const LUN\n");
printf(" msconn -o nc -l /dev/ramx\n");
}

/****************************************************************************
* Public Functions
****************************************************************************/
Expand All @@ -410,9 +448,57 @@ static void usbmsc_disconnect(FAR void *handle)
int main(int argc, FAR char *argv[])
{
struct boardioc_usbdev_ctrl_s ctrl;
struct usbmsc_lun_t luns[CONFIG_SYSTEM_USBMSC_NLUNS +
CONFIG_SYSTEM_USBMSC_EXT_NLUNS];
int num_luns;
int flags;
#if CONFIG_SYSTEM_USBMSC_NLUNS > 0
bool enable_const_luns;
#endif
FAR void *handle = NULL;
int ret;

num_luns = 0;
flags = O_RDWR;
#if CONFIG_SYSTEM_USBMSC_NLUNS > 0
enable_const_luns = true;
#endif
memset(luns, 0, sizeof(luns));

while ((ret = getopt(argc, argv, "hl:o:")) != -1)
{
switch (ret)
{
case 'o':
if (!strcmp("nc", optarg))
{
#if CONFIG_SYSTEM_USBMSC_NLUNS > 0
enable_const_luns = false;
#endif
}
else if (!strcmp("ro", optarg))
{
flags = O_RDONLY;
}
else if (!strcmp("rw", optarg))
{
flags = O_RDWR;
}
break;
case 'l':
LUN_ADD_BIND(luns, num_luns, optarg, flags);
break;
case 'h':
help_conn();
return 0;
break;
default:
help_conn();
return EINVAL;
break;
}
}

/* If this program is implemented as the NSH 'msconn' command, then we
* need to do a little error checking to assure that we are not being
* called re-entrantly.
Expand All @@ -428,6 +514,39 @@ int main(int argc, FAR char *argv[])
return EXIT_FAILURE;
}

/* Add const LUNs */

#if CONFIG_SYSTEM_USBMSC_NLUNS > 0
if (enable_const_luns)
{
# ifdef CONFIG_SYSTEM_USBMSC_WRITEPROTECT1
LUN_ADD_BIND(luns, num_luns, CONFIG_SYSTEM_USBMSC_DEVPATH1, O_RDONLY);
# else
LUN_ADD_BIND(luns, num_luns, CONFIG_SYSTEM_USBMSC_DEVPATH1, O_RDWR);
# endif
# if CONFIG_SYSTEM_USBMSC_NLUNS > 1
# ifdef CONFIG_SYSTEM_USBMSC_WRITEPROTECT2
LUN_ADD_BIND(luns, num_luns, CONFIG_SYSTEM_USBMSC_DEVPATH2, O_RDONLY);
# else
LUN_ADD_BIND(luns, num_luns, CONFIG_SYSTEM_USBMSC_DEVPATH2, O_RDWR);
# endif
# if CONFIG_SYSTEM_USBMSC_NLUNS > 2
# ifdef CONFIG_SYSTEM_USBMSC_WRITEPROTECT3
LUN_ADD_BIND(luns, num_luns, CONFIG_SYSTEM_USBMSC_DEVPATH3, O_RDONLY);
# else
LUN_ADD_BIND(luns, num_luns, CONFIG_SYSTEM_USBMSC_DEVPATH3, O_RDWR);
# endif
# endif
# endif
}
#endif

if (num_luns <= 0)
{
help_conn();
return EINVAL;
}

#ifdef CONFIG_SYSTEM_USBMSC_DEBUGMM
g_usbmsc.mmstart = mallinfo();
g_usbmsc.mmprevious = g_usbmsc.mmstart;
Expand Down Expand Up @@ -462,8 +581,8 @@ int main(int argc, FAR char *argv[])
/* Then exports the LUN(s) */

printf("mcsonn_main: Configuring with NLUNS=%d\n",
CONFIG_SYSTEM_USBMSC_NLUNS);
ret = usbmsc_configure(CONFIG_SYSTEM_USBMSC_NLUNS, &handle);
num_luns);
ret = usbmsc_configure(num_luns, &handle);
if (ret < 0)
{
printf("mcsonn_main: usbmsc_configure failed: %d\n", -ret);
Expand All @@ -478,73 +597,24 @@ int main(int argc, FAR char *argv[])
printf("mcsonn_main: handle=%p\n", handle);
check_test_memory_usage("After usbmsc_configure()");

printf("mcsonn_main: Bind LUN=0 to %s\n",
CONFIG_SYSTEM_USBMSC_DEVPATH1);

#ifdef CONFIG_SYSTEM_USBMSC_WRITEPROTECT1
ret = usbmsc_bindlun(handle, CONFIG_SYSTEM_USBMSC_DEVPATH1, 0, 0, 0,
true);
#else
ret = usbmsc_bindlun(handle, CONFIG_SYSTEM_USBMSC_DEVPATH1, 0, 0, 0,
false);
#endif
if (ret < 0)
{
printf("mcsonn_main: usbmsc_bindlun failed for LUN 1 using %s: %d\n",
CONFIG_SYSTEM_USBMSC_DEVPATH1, -ret);
usbmsc_disconnect(handle);
return EXIT_FAILURE;
}

check_test_memory_usage("After usbmsc_bindlun()");

#if CONFIG_SYSTEM_USBMSC_NLUNS > 1

printf("mcsonn_main: Bind LUN=1 to %s\n",
CONFIG_SYSTEM_USBMSC_DEVPATH2);

#ifdef CONFIG_SYSTEM_USBMSC_WRITEPROTECT2
ret = usbmsc_bindlun(handle, CONFIG_SYSTEM_USBMSC_DEVPATH2, 1, 0, 0,
true);
#else
ret = usbmsc_bindlun(handle, CONFIG_SYSTEM_USBMSC_DEVPATH2, 1, 0, 0,
false);
#endif
if (ret < 0)
while (--num_luns >= 0 && luns[num_luns].path != NULL)
{
printf("mcsonn_main: usbmsc_bindlun failed for LUN 2 using %s: %d\n",
CONFIG_SYSTEM_USBMSC_DEVPATH2, -ret);
usbmsc_disconnect(handle);
return EXIT_FAILURE;
}

check_test_memory_usage("After usbmsc_bindlun() #2");

#if CONFIG_SYSTEM_USBMSC_NLUNS > 2
printf("mcsonn_main: Bind LUN=%d to %s\n",
num_luns, luns[num_luns].path);

printf("mcsonn_main: Bind LUN=2 to %s\n",
CONFIG_SYSTEM_USBMSC_DEVPATH3);
ret = usbmsc_bindlun(handle, luns[num_luns].path, 0, 0, 0,
luns[num_luns].flags & O_WROK ? false : true);
if (ret < 0)
{
printf("mcsonn_main: usbmsc_bindlun failed for LUN %d using %s: "
"%d\n", num_luns, luns[num_luns].path, -ret);
usbmsc_disconnect(handle);
return EXIT_FAILURE;
}

#ifdef CONFIG_SYSTEM_USBMSC_WRITEPROTECT3
ret = usbmsc_bindlun(handle, CONFIG_SYSTEM_USBMSC_DEVPATH3, 2, 0, 0,
true);
#else
ret = usbmsc_bindlun(handle, CONFIG_SYSTEM_USBMSC_DEVPATH3, 2, 0, 0,
false);
#endif
if (ret < 0)
{
printf("mcsonn_main: usbmsc_bindlun failed for LUN 3 using %s: %d\n",
CONFIG_SYSTEM_USBMSC_DEVPATH3, -ret);
usbmsc_disconnect(handle);
return EXIT_FAILURE;
check_test_memory_usage("After usbmsc_bindlun()");
}

check_test_memory_usage("After usbmsc_bindlun() #3");

#endif
#endif

ret = usbmsc_exportluns(handle);
if (ret < 0)
{
Expand Down

0 comments on commit f8b23df

Please sign in to comment.