system/usbmsc: Add support for setting paths that bind to LUN at runtime

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

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
wangjianyu3 2024-12-02 17:02:43 +08:00 committed by Xiang Xiao
parent 6600a5fd08
commit b08c29617b
3 changed files with 133 additions and 117 deletions

View file

@ -18,19 +18,21 @@ if SYSTEM_USBMSC
config SYSTEM_USBMSC_NLUNS
int "Number of LUNs"
default 1
default 8
---help---
Defines the number of logical units (LUNs) exported by the USB
Defines the max 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.
(or partition of a block driver). May be 1, 2, or 3.
config SYSTEM_USBMSC_DEVMINOR1
int "LUN1 Minor Device Number"
default 0
default -1
---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.
Default -1 means the LUN is disabled.
if SYSTEM_USBMSC_DEVMINOR1 > -1
config SYSTEM_USBMSC_DEVPATH1
string "LUN1 Device Path"
@ -46,13 +48,17 @@ config SYSTEM_USBMSC_WRITEPROTECT1
Enable this if you want to write-protect the first LUN. Default is
off.
endif
config SYSTEM_USBMSC_DEVMINOR2
int "LUN2 Minor Device Number"
default 1
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_USBMSC_NLUNS < 2. Default is one.
Default -1 means the LUN is disabled.
if SYSTEM_USBMSC_DEVMINOR2 > -1
config SYSTEM_USBMSC_DEVPATH2
string "LUN2 Device Path"
@ -68,13 +74,17 @@ config SYSTEM_USBMSC_WRITEPROTECT2
Enable this if you want to write-protect the second LUN. Ignored if
SYSTEM_USBMSC_NLUNS < 2. Default is off.
endif
config SYSTEM_USBMSC_DEVMINOR3
int "LUN3 Minor Device Number"
default 2
default -1
---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_USBMSC_NLUNS < 3. Default is two.
Default -1 means the LUN is disabled.
if SYSTEM_USBMSC_DEVMINOR3 > -1
config SYSTEM_USBMSC_DEVPATH3
string "LUN3 Device Path"
@ -90,6 +100,8 @@ config SYSTEM_USBMSC_WRITEPROTECT3
Enable this if you want to write-protect the third LUN. Ignored if
SYSTEM_USBMSC_NLUNS < 3. Default is off.
endif
config SYSTEM_USBMSC_DEBUGMM
bool "USB MSC MM Debug"
default n

View file

@ -32,48 +32,6 @@
* Pre-Processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_SYSTEM_USBMSC_NLUNS
# define CONFIG_SYSTEM_USBMSC_NLUNS 1
#endif
#ifndef CONFIG_SYSTEM_USBMSC_DEVMINOR1
# define CONFIG_SYSTEM_USBMSC_DEVMINOR1 0
#endif
#ifndef CONFIG_SYSTEM_USBMSC_DEVPATH1
# define CONFIG_SYSTEM_USBMSC_DEVPATH1 "/dev/mmcsd0"
#endif
#if CONFIG_SYSTEM_USBMSC_NLUNS > 1
# ifndef CONFIG_SYSTEM_USBMSC_DEVMINOR2
# error "CONFIG_SYSTEM_USBMSC_DEVMINOR2 for LUN=2"
# endif
# ifndef CONFIG_SYSTEM_USBMSC_DEVPATH2
# error "CONFIG_SYSTEM_USBMSC_DEVPATH2 for LUN=2"
# endif
# if CONFIG_SYSTEM_USBMSC_NLUNS > 2
# ifndef CONFIG_SYSTEM_USBMSC_DEVMINOR3
# error "CONFIG_SYSTEM_USBMSC_DEVMINOR2 for LUN=3"
# endif
# ifndef CONFIG_SYSTEM_USBMSC_DEVPATH3
# error "CONFIG_SYSTEM_USBMSC_DEVPATH3 for LUN=3"
# endif
# if CONFIG_SYSTEM_USBMSC_NLUNS > 3
# error "CONFIG_SYSTEM_USBMSC_NLUNS must be {1,2,3}"
# endif
# else
# undef CONFIG_SYSTEM_USBMSC_DEVMINOR3
# undef CONFIG_SYSTEM_USBMSC_DEVPATH3
# endif
#else
# undef CONFIG_SYSTEM_USBMSC_DEVMINOR2
# undef CONFIG_SYSTEM_USBMSC_DEVPATH2
# undef CONFIG_SYSTEM_USBMSC_DEVMINOR3
# undef CONFIG_SYSTEM_USBMSC_DEVPATH3
#endif
/****************************************************************************
* Public Types
****************************************************************************/

View file

@ -27,6 +27,7 @@
#include <sys/types.h>
#include <sys/boardctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
@ -80,6 +81,26 @@
#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) \
do \
{ \
l[i].path = p; \
l[i].flags = f; \
i++; \
} while (0)
/****************************************************************************
* Private Types
****************************************************************************/
struct usbmsc_lun_t
{
FAR const char *path; /* The full path to the block driver */
int flags; /* Access modes */
};
/****************************************************************************
* Private Data
****************************************************************************/
@ -392,6 +413,23 @@ 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(" 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");
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -410,9 +448,34 @@ 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];
int num_luns = 0;
int flags = O_RDWR;
FAR void *handle = NULL;
int ret;
memset(luns, 0, sizeof(luns));
while ((ret = getopt(argc, argv, "l:o:")) != -1)
{
switch (ret)
{
case 'o':
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;
}
}
/* 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.
@ -428,6 +491,38 @@ int main(int argc, FAR char *argv[])
return EXIT_FAILURE;
}
/* Add const LUNs */
#if CONFIG_SYSTEM_USBMSC_DEVMINOR1 > -1
# 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
#endif
#if CONFIG_SYSTEM_USBMSC_DEVMINOR2 > -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
#endif
#if CONFIG_SYSTEM_USBMSC_DEVMINOR3 > -1
# 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
if (num_luns <= 0)
{
help_conn();
return EINVAL;
}
#ifdef CONFIG_SYSTEM_USBMSC_DEBUGMM
g_usbmsc.mmstart = mallinfo();
g_usbmsc.mmprevious = g_usbmsc.mmstart;
@ -462,8 +557,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);
@ -478,73 +573,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)
while (--num_luns >= 0 && luns[num_luns].path != NULL)
{
printf("mcsonn_main: usbmsc_bindlun failed for LUN 1 using %s: %d\n",
CONFIG_SYSTEM_USBMSC_DEVPATH1, -ret);
usbmsc_disconnect(handle);
return EXIT_FAILURE;
printf("mcsonn_main: Bind LUN=%d to %s\n",
num_luns, luns[num_luns].path);
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;
}
check_test_memory_usage("After usbmsc_bindlun()");
}
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)
{
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=2 to %s\n",
CONFIG_SYSTEM_USBMSC_DEVPATH3);
#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() #3");
#endif
#endif
ret = usbmsc_exportluns(handle);
if (ret < 0)
{