Added USB MSC state change notifier in notifier work queue.
Added USB MSC automount for Freedom K28 using the above.
This commit is contained in:
parent
8807a52de6
commit
02a9228c1f
@ -33,4 +33,34 @@ config FRDMK28F_SDHC_AUTOMOUNT_UDELAY
|
|||||||
default 2000
|
default 2000
|
||||||
|
|
||||||
endif # FRDMK28F_SDHC_AUTOMOUNT
|
endif # FRDMK28F_SDHC_AUTOMOUNT
|
||||||
|
|
||||||
|
config FRDMK28F_USB_AUTOMOUNT
|
||||||
|
bool "USB Mass Storage automounter"
|
||||||
|
default n
|
||||||
|
depends on USBHOST_MSC && USBHOST_MSC_NOTIFIER
|
||||||
|
|
||||||
|
if FRDMK28F_USB_AUTOMOUNT
|
||||||
|
|
||||||
|
config FRDMK28F_USB_AUTOMOUNT_FSTYPE
|
||||||
|
string "USB file system type"
|
||||||
|
default "vfat"
|
||||||
|
|
||||||
|
config FRDMK28F_USB_AUTOMOUNT_BLKDEV
|
||||||
|
string "USB block device prefix"
|
||||||
|
default "/dev/sd"
|
||||||
|
|
||||||
|
config FRDMK28F_USB_AUTOMOUNT_MOUNTPOINT
|
||||||
|
string "USB mount point prefix"
|
||||||
|
default "/mnt/usb"
|
||||||
|
|
||||||
|
config FRDMK28F_USB_AUTOMOUNT_NUM_BLKDEV
|
||||||
|
int "Number of block devices to monitor."
|
||||||
|
range 1 26
|
||||||
|
default 4
|
||||||
|
|
||||||
|
config FRDMK28F_USB_AUTOMOUNT_UDELAY
|
||||||
|
int "USB unmount retry delay (milliseconds)"
|
||||||
|
default 2000
|
||||||
|
|
||||||
|
endif # FRDMK28F_USB_AUTOMOUNT
|
||||||
endif # ARCH_BOARD_FREEDOM_K28F
|
endif # ARCH_BOARD_FREEDOM_K28F
|
||||||
|
@ -52,7 +52,13 @@
|
|||||||
/* Assume we have everything */
|
/* Assume we have everything */
|
||||||
|
|
||||||
#define HAVE_MMCSD 1
|
#define HAVE_MMCSD 1
|
||||||
#define HAVE_AUTOMOUNTER 1
|
#define HAVE_USB_MSC 1
|
||||||
|
#ifdef CONFIG_FRDMK28F_SDHC_AUTOMOUNT
|
||||||
|
# define HAVE_SDHC_AUTOMOUNTER 1
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_FRDMK28F_USB_AUTOMOUNT
|
||||||
|
# define HAVE_USB_AUTOMOUNTER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SD card support */
|
/* SD card support */
|
||||||
|
|
||||||
@ -77,6 +83,12 @@
|
|||||||
# define MMSCD_MINOR 0
|
# define MMSCD_MINOR 0
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
/* Check for USB_HOST and USB_MSC */
|
||||||
|
#if defined(CONFIG_DISABLE_MOUNTPOINT) || \
|
||||||
|
!defined(CONFIG_KINETIS_USBHS) || !defined(CONFIG_USBHOST_MSC)
|
||||||
|
# undef HAVE_USB_MSC
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We expect to receive GPIO interrupts for card insertion events */
|
/* We expect to receive GPIO interrupts for card insertion events */
|
||||||
|
|
||||||
# ifndef CONFIG_KINETIS_GPIOIRQ
|
# ifndef CONFIG_KINETIS_GPIOIRQ
|
||||||
@ -92,17 +104,16 @@
|
|||||||
/* Automounter */
|
/* Automounter */
|
||||||
|
|
||||||
#if !defined(CONFIG_FS_AUTOMOUNTER) || !defined(HAVE_MMCSD)
|
#if !defined(CONFIG_FS_AUTOMOUNTER) || !defined(HAVE_MMCSD)
|
||||||
# undef HAVE_AUTOMOUNTER
|
# undef HAVE_SDHC_AUTOMOUNTER
|
||||||
# undef CONFIG_FRDMK28F_SDHC_AUTOMOUNT
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_FRDMK28F_SDHC_AUTOMOUNT
|
#if !defined(HAVE_USB_MSC) || !defined(CONFIG_USBHOST_MSC_NOTIFIER)
|
||||||
# undef HAVE_AUTOMOUNTER
|
# undef HAVE_USB_AUTOMOUNTER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Automounter defaults */
|
/* Automounter defaults */
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
|
|
||||||
# ifndef CONFIG_FRDMK28F_SDHC_AUTOMOUNT_FSTYPE
|
# ifndef CONFIG_FRDMK28F_SDHC_AUTOMOUNT_FSTYPE
|
||||||
# define CONFIG_FRDMK28F_SDHC_AUTOMOUNT_FSTYPE "vfat"
|
# define CONFIG_FRDMK28F_SDHC_AUTOMOUNT_FSTYPE "vfat"
|
||||||
@ -123,7 +134,30 @@
|
|||||||
# ifndef CONFIG_FRDMK28F_SDHC_AUTOMOUNT_UDELAY
|
# ifndef CONFIG_FRDMK28F_SDHC_AUTOMOUNT_UDELAY
|
||||||
# define CONFIG_FRDMK28F_SDHC_AUTOMOUNT_UDELAY 2000
|
# define CONFIG_FRDMK28F_SDHC_AUTOMOUNT_UDELAY 2000
|
||||||
# endif
|
# endif
|
||||||
#endif /* HAVE_AUTOMOUNTER */
|
#endif /* HAVE_SDHC_AUTOMOUNTER */
|
||||||
|
|
||||||
|
#ifdef HAVE_USB_AUTOMOUNTER
|
||||||
|
|
||||||
|
# ifndef CONFIG_FRDMK28F_USB_AUTOMOUNT_FSTYPE
|
||||||
|
# define CONFIG_FRDMK28F_USB_AUTOMOUNT_FSTYPE "vfat"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef CONFIG_FRDMK28F_USB_AUTOMOUNT_BLKDEV
|
||||||
|
# define CONFIG_FRDMK28F_USB_AUTOMOUNT_BLKDEV "/dev/sd"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef CONFIG_FRDMK28F_USB_AUTOMOUNT_MOUNTPOINT
|
||||||
|
# define CONFIG_FRDMK28F_USB_AUTOMOUNT_MOUNTPOINT "/mnt/usb"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef CONFIG_FRDMK28F_USB_AUTOMOUNT_NUM_BLKDEV
|
||||||
|
# define CONFIG_FRDMK28F_USB_AUTOMOUNT_NUM_BLKDEV 4
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef CONFIG_FRDMK28F_USB_AUTOMOUNT_UDELAY
|
||||||
|
# define CONFIG_FRDMK28F_USB_AUTOMOUNT_UDELAY 2000
|
||||||
|
# endif
|
||||||
|
#endif /* HAVE_USB_AUTOMOUNTER */
|
||||||
|
|
||||||
/* Freedom-K28F GPIOs *******************************************************/
|
/* Freedom-K28F GPIOs *******************************************************/
|
||||||
|
|
||||||
@ -279,7 +313,7 @@ int k28_sdhc_initialize(void);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
bool k28_cardinserted(void);
|
bool k28_cardinserted(void);
|
||||||
#else
|
#else
|
||||||
# define k28_cardinserted() (false)
|
# define k28_cardinserted() (false)
|
||||||
@ -293,32 +327,14 @@ bool k28_cardinserted(void);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
bool k28_writeprotected(void);
|
bool k28_writeprotected(void);
|
||||||
#else
|
#else
|
||||||
# define k28_writeprotected() (false)
|
# define k28_writeprotected() (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: k28_automount_initialize
|
* Name: k28_sdhc_automount_event
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Configure auto-mounter for the configured SDHC slot
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
|
||||||
void k28_automount_initialize(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: k28_automount_event
|
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* The SDHC card detection logic has detected an insertion or removal
|
* The SDHC card detection logic has detected an insertion or removal
|
||||||
@ -338,8 +354,26 @@ void k28_automount_initialize(void);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
void k28_automount_event(bool inserted);
|
void k28_sdhc_automount_event(bool inserted);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: k28_automount_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Configure auto-mounter for the configured SDHC slot
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(HAVE_SDHC_AUTOMOUNTER) || defined(HAVE_USB_AUTOMOUNTER)
|
||||||
|
void k28_automount_initialize(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "freedom-k28f.h"
|
#include "freedom-k28f.h"
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@ -80,11 +80,11 @@ struct k28_automount_config_s
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int k28_attach(FAR const struct automount_lower_s *lower,
|
static int k28_sdhc_attach(FAR const struct automount_lower_s *lower,
|
||||||
automount_handler_t isr, FAR void *arg);
|
automount_handler_t isr, FAR void *arg);
|
||||||
static void k28_enable(FAR const struct automount_lower_s *lower,
|
static void k28_sdhc_enable(FAR const struct automount_lower_s *lower,
|
||||||
bool enable);
|
bool enable);
|
||||||
static bool k28_inserted(FAR const struct automount_lower_s *lower);
|
static bool k28_sdhc_inserted(FAR const struct automount_lower_s *lower);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
@ -100,9 +100,9 @@ static const struct k28_automount_config_s g_sdhc_config =
|
|||||||
.mountpoint = CONFIG_FRDMK28F_SDHC_AUTOMOUNT_MOUNTPOINT,
|
.mountpoint = CONFIG_FRDMK28F_SDHC_AUTOMOUNT_MOUNTPOINT,
|
||||||
.ddelay = MSEC2TICK(CONFIG_FRDMK28F_SDHC_AUTOMOUNT_DDELAY),
|
.ddelay = MSEC2TICK(CONFIG_FRDMK28F_SDHC_AUTOMOUNT_DDELAY),
|
||||||
.udelay = MSEC2TICK(CONFIG_FRDMK28F_SDHC_AUTOMOUNT_UDELAY),
|
.udelay = MSEC2TICK(CONFIG_FRDMK28F_SDHC_AUTOMOUNT_UDELAY),
|
||||||
.attach = k28_attach,
|
.attach = k28_sdhc_attach,
|
||||||
.enable = k28_enable,
|
.enable = k28_sdhc_enable,
|
||||||
.inserted = k28_inserted
|
.inserted = k28_sdhc_inserted
|
||||||
},
|
},
|
||||||
.state = &g_sdhc_state
|
.state = &g_sdhc_state
|
||||||
};
|
};
|
||||||
@ -112,7 +112,7 @@ static const struct k28_automount_config_s g_sdhc_config =
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: k28_attach
|
* Name: k28_sdhc_attach
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Attach a new SDHC event handler
|
* Attach a new SDHC event handler
|
||||||
@ -127,7 +127,7 @@ static const struct k28_automount_config_s g_sdhc_config =
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int k28_attach(FAR const struct automount_lower_s *lower,
|
static int k28_sdhc_attach(FAR const struct automount_lower_s *lower,
|
||||||
automount_handler_t isr, FAR void *arg)
|
automount_handler_t isr, FAR void *arg)
|
||||||
{
|
{
|
||||||
FAR const struct k28_automount_config_s *config;
|
FAR const struct k28_automount_config_s *config;
|
||||||
@ -152,7 +152,7 @@ static int k28_attach(FAR const struct automount_lower_s *lower,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: k28_enable
|
* Name: k28_sdhc_enable
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Enable card insertion/removal event detection
|
* Enable card insertion/removal event detection
|
||||||
@ -166,7 +166,7 @@ static int k28_attach(FAR const struct automount_lower_s *lower,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void k28_enable(FAR const struct automount_lower_s *lower,
|
static void k28_sdhc_enable(FAR const struct automount_lower_s *lower,
|
||||||
bool enable)
|
bool enable)
|
||||||
{
|
{
|
||||||
FAR const struct k28_automount_config_s *config;
|
FAR const struct k28_automount_config_s *config;
|
||||||
@ -204,7 +204,7 @@ static void k28_enable(FAR const struct automount_lower_s *lower,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: k28_inserted
|
* Name: k28_sdhc_inserted
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Check if a card is inserted into the slot.
|
* Check if a card is inserted into the slot.
|
||||||
@ -217,7 +217,7 @@ static void k28_enable(FAR const struct automount_lower_s *lower,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static bool k28_inserted(FAR const struct automount_lower_s *lower)
|
static bool k28_sdhc_inserted(FAR const struct automount_lower_s *lower)
|
||||||
{
|
{
|
||||||
return k28_cardinserted();
|
return k28_cardinserted();
|
||||||
}
|
}
|
||||||
@ -226,6 +226,59 @@ static bool k28_inserted(FAR const struct automount_lower_s *lower)
|
|||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: k28_sdhc_automount_event
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The SDHC card detection logic has detected an insertion or removal
|
||||||
|
* event.
|
||||||
|
* It has already scheduled the MMC/SD block driver operations.
|
||||||
|
* Now we need to schedule the auto-mount event which will occur with a
|
||||||
|
* substantial delay to make sure that everything has settle down.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* slotno - Identifies the SDHC0 slot: SDHC0_SLOTNO or SDHC1_SLOTNO.
|
||||||
|
* There is a terminology problem here: Each SDHC supports two slots,
|
||||||
|
* slot A and slot B. Only slot A is used.
|
||||||
|
* So this is not a really a slot, but an HSCMI peripheral number.
|
||||||
|
* inserted - True if the card is inserted in the slot. False otherwise.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Interrupts are disabled.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void k28_sdhc_automount_event(bool inserted)
|
||||||
|
{
|
||||||
|
FAR const struct k28_automount_config_s *config = &g_sdhc_config;
|
||||||
|
FAR struct k28_automount_state_s *state = &g_sdhc_state;
|
||||||
|
|
||||||
|
/* Is the auto-mounter interrupt attached? */
|
||||||
|
|
||||||
|
if (state->handler)
|
||||||
|
{
|
||||||
|
/* Yes.. Have we been asked to hold off interrupts? */
|
||||||
|
|
||||||
|
if (!state->enable)
|
||||||
|
{
|
||||||
|
/* Yes.. just remember that there is a pending interrupt. We will
|
||||||
|
* deliver the interrupt when interrupts are "re-enabled."
|
||||||
|
*/
|
||||||
|
|
||||||
|
state->pending = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No.. forward the event to the handler */
|
||||||
|
|
||||||
|
state->handler(&config->lower, state->arg, inserted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: k28_automount_initialize
|
* Name: k28_automount_initialize
|
||||||
*
|
*
|
||||||
@ -255,56 +308,4 @@ void k28_automount_initialize(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
#endif /* HAVE_SDHC_AUTOMOUNTER */
|
||||||
* Name: k28_automount_event
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* The SDHC card detection logic has detected an insertion or removal event.
|
|
||||||
* It has already scheduled the MMC/SD block driver operations.
|
|
||||||
* Now we need to schedule the auto-mount event which will occur with a
|
|
||||||
* substantial delay to make sure that everything has settle down.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* slotno - Identifies the SDHC0 slot: SDHC0_SLOTNO or SDHC1_SLOTNO.
|
|
||||||
* There is a terminology problem here: Each SDHC supports two slots,
|
|
||||||
* slot A and slot B. Only slot A is used.
|
|
||||||
* So this is not a really a slot, but an HSCMI peripheral number.
|
|
||||||
* inserted - True if the card is inserted in the slot. False otherwise.
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* Interrupts are disabled.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void k28_automount_event(bool inserted)
|
|
||||||
{
|
|
||||||
FAR const struct k28_automount_config_s *config = &g_sdhc_config;
|
|
||||||
FAR struct k28_automount_state_s *state = &g_sdhc_state;
|
|
||||||
|
|
||||||
/* Is the auto-mounter interrupt attached? */
|
|
||||||
|
|
||||||
if (state->handler)
|
|
||||||
{
|
|
||||||
/* Yes.. Have we been asked to hold off interrupts? */
|
|
||||||
|
|
||||||
if (!state->enable)
|
|
||||||
{
|
|
||||||
/* Yes.. just remember that there is a pending interrupt. We will
|
|
||||||
* deliver the interrupt when interrupts are "re-enabled."
|
|
||||||
*/
|
|
||||||
|
|
||||||
state->pending = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No.. forward the event to the handler */
|
|
||||||
|
|
||||||
state->handler(&config->lower, state->arg, inserted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_AUTOMOUNTER */
|
|
||||||
|
@ -118,12 +118,6 @@ int k28_bringup(void)
|
|||||||
#endif /* CONFIG_FRDMK28F_SDHC_MOUNT */
|
#endif /* CONFIG_FRDMK28F_SDHC_MOUNT */
|
||||||
#endif /* HAVE_MMCSD */
|
#endif /* HAVE_MMCSD */
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
|
||||||
/* Initialize the auto-mounter */
|
|
||||||
|
|
||||||
k28_automount_initialize();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_USBDEV) && defined(CONFIG_KINETIS_USBOTG)
|
#if defined(CONFIG_USBDEV) && defined(CONFIG_KINETIS_USBOTG)
|
||||||
if (k28_usbdev_initialize)
|
if (k28_usbdev_initialize)
|
||||||
{
|
{
|
||||||
@ -154,9 +148,17 @@ int k28_bringup(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_USBHOST) && defined(CONFIG_KINETIS_USBHS)
|
#if defined(CONFIG_USBHOST) && defined(CONFIG_KINETIS_USBHS)
|
||||||
|
/* Initialize the USB highspeed host */
|
||||||
|
|
||||||
k28_usbhost_initialize();
|
k28_usbhost_initialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
|
/* Initialize the auto-mounter */
|
||||||
|
|
||||||
|
k28_automount_initialize();
|
||||||
|
#endif
|
||||||
|
|
||||||
UNUSED(ret);
|
UNUSED(ret);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -109,15 +109,17 @@ static void k28_mediachange(void)
|
|||||||
{
|
{
|
||||||
mcinfo("Media change: %d->%d\n", g_sdhc.inserted, inserted);
|
mcinfo("Media change: %d->%d\n", g_sdhc.inserted, inserted);
|
||||||
|
|
||||||
/* Yes.. perform the appropriate action (this might need some debounce). */
|
/* Yes.. perform the appropriate action
|
||||||
|
* (this might need some debounce).
|
||||||
|
*/
|
||||||
|
|
||||||
g_sdhc.inserted = inserted;
|
g_sdhc.inserted = inserted;
|
||||||
sdhc_mediachange(g_sdhc.sdhc, inserted);
|
sdhc_mediachange(g_sdhc.sdhc, inserted);
|
||||||
|
|
||||||
#ifdef CONFIG_FRDMK28F_SDHC_AUTOMOUNT
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
/* Let the automounter know about the insertion event */
|
/* Let the automounter know about the insertion event */
|
||||||
|
|
||||||
k28_automount_event(k28_cardinserted());
|
k28_sdhc_automount_event(k28_cardinserted());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,7 +182,8 @@ int k28_sdhc_initialize(void)
|
|||||||
ret = mmcsd_slotinitialize(MMSCD_MINOR, g_sdhc.sdhc);
|
ret = mmcsd_slotinitialize(MMSCD_MINOR, g_sdhc.sdhc);
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR, "ERROR: Failed to bind SDHC to the MMC/SD driver: %d\n",
|
syslog(LOG_ERR,
|
||||||
|
"ERROR: Failed to bind SDHC to the MMC/SD driver: %d\n",
|
||||||
ret);
|
ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -205,7 +208,7 @@ int k28_sdhc_initialize(void)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
bool k28_cardinserted(void)
|
bool k28_cardinserted(void)
|
||||||
{
|
{
|
||||||
bool inserted;
|
bool inserted;
|
||||||
@ -228,7 +231,7 @@ bool k28_cardinserted(void)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef HAVE_AUTOMOUNTER
|
#ifdef HAVE_SDHC_AUTOMOUNTER
|
||||||
bool k28_writeprotected(void)
|
bool k28_writeprotected(void)
|
||||||
{
|
{
|
||||||
/* There are no write protect pins */
|
/* There are no write protect pins */
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -54,6 +55,8 @@
|
|||||||
#include <nuttx/usb/usbdev_trace.h>
|
#include <nuttx/usb/usbdev_trace.h>
|
||||||
#include <nuttx/usb/ehci.h>
|
#include <nuttx/usb/ehci.h>
|
||||||
|
|
||||||
|
#include <sys/mount.h>
|
||||||
|
|
||||||
#include <kinetis_usbhshost.h>
|
#include <kinetis_usbhshost.h>
|
||||||
|
|
||||||
#include "arm_arch.h"
|
#include "arm_arch.h"
|
||||||
@ -88,6 +91,19 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static int ehci_waiter(int argc, char *argv[]);
|
||||||
|
static void ehci_hwinit(void);
|
||||||
|
|
||||||
|
# ifdef HAVE_USB_AUTOMOUNTER
|
||||||
|
static void usb_msc_connect(FAR void *arg);
|
||||||
|
static void unmount_retry_timeout(int argc, uint32_t arg1, ...);
|
||||||
|
static void usb_msc_disconnect(FAR void *arg);
|
||||||
|
# endif
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -96,6 +112,12 @@
|
|||||||
|
|
||||||
static struct usbhost_connection_s *g_ehciconn;
|
static struct usbhost_connection_s *g_ehciconn;
|
||||||
|
|
||||||
|
# ifdef HAVE_USB_AUTOMOUNTER
|
||||||
|
/* Unmount retry timer */
|
||||||
|
|
||||||
|
static WDOG_ID g_umount_tmr[CONFIG_FRDMK28F_USB_AUTOMOUNT_NUM_BLKDEV];
|
||||||
|
# endif
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -232,6 +254,152 @@ static void ehci_hwinit(void)
|
|||||||
putreg32(regval, KINETIS_USBHSPHY_CTRL);
|
putreg32(regval, KINETIS_USBHSPHY_CTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef HAVE_USB_AUTOMOUNTER
|
||||||
|
/*****************************************************************************
|
||||||
|
* Name: usb_msc_connect
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Mount the USB mass storage device
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static void usb_msc_connect(FAR void *arg)
|
||||||
|
{
|
||||||
|
int index = (int)arg;
|
||||||
|
char sdchar = 'a' + index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
char blkdev[32];
|
||||||
|
char mntpnt[32];
|
||||||
|
|
||||||
|
DEBUGASSERT(index >= 0 && index < CONFIG_FRDMK28F_USB_AUTOMOUNT_NUM_BLKDEV);
|
||||||
|
|
||||||
|
wd_cancel(g_umount_tmr[index]);
|
||||||
|
|
||||||
|
/* Resetup the event. */
|
||||||
|
|
||||||
|
usbhost_msc_notifier_setup(usb_msc_connect, WORK_USB_MSC_CONNECT,
|
||||||
|
sdchar, arg);
|
||||||
|
|
||||||
|
snprintf(blkdev, sizeof(blkdev), "%s%c",
|
||||||
|
CONFIG_FRDMK28F_USB_AUTOMOUNT_BLKDEV, sdchar);
|
||||||
|
snprintf(mntpnt, sizeof(mntpnt), "%s%c",
|
||||||
|
CONFIG_FRDMK28F_USB_AUTOMOUNT_MOUNTPOINT, sdchar);
|
||||||
|
|
||||||
|
/* Mount */
|
||||||
|
|
||||||
|
ret = mount((FAR const char *)blkdev, (FAR const char *)mntpnt,
|
||||||
|
CONFIG_FRDMK28F_USB_AUTOMOUNT_FSTYPE, 0, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = get_errno();
|
||||||
|
DEBUGASSERT(errcode > 0);
|
||||||
|
|
||||||
|
ferr("ERROR: Mount failed: %d\n", errcode);
|
||||||
|
UNUSED(errcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Name: unmount_retry_timeout
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* A previous unmount failed because the volume was busy... busy meaning
|
||||||
|
* the volume could not be unmounted because there are open references
|
||||||
|
* the files or directories in the volume. When this failure occurred,
|
||||||
|
* the unmount logic setup a delay and this function is called as a result
|
||||||
|
* of that delay timeout.
|
||||||
|
*
|
||||||
|
* This function will attempt the unmount again.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* Standard wdog timeout parameters
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static void unmount_retry_timeout(int argc, uint32_t arg1, ...)
|
||||||
|
{
|
||||||
|
int index = (int)arg1;
|
||||||
|
char sdchar = 'a' + index;
|
||||||
|
|
||||||
|
finfo("Timeout!\n");
|
||||||
|
DEBUGASSERT(argc == 1 && \
|
||||||
|
index >= 0 && index < CONFIG_FRDMK28F_USB_AUTOMOUNT_NUM_BLKDEV);
|
||||||
|
|
||||||
|
/* Resend the notification. */
|
||||||
|
|
||||||
|
usbhost_msc_notifier_signal(WORK_USB_MSC_DISCONNECT, sdchar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Name: usb_msc_disconnect
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Unmount the USB mass storage device
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static void usb_msc_disconnect(FAR void *arg)
|
||||||
|
{
|
||||||
|
int index = (int)arg;
|
||||||
|
char sdchar = 'a' + index;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
char mntpnt[32];
|
||||||
|
|
||||||
|
DEBUGASSERT(index >= 0 && index < CONFIG_FRDMK28F_USB_AUTOMOUNT_NUM_BLKDEV);
|
||||||
|
|
||||||
|
wd_cancel(g_umount_tmr[index]);
|
||||||
|
|
||||||
|
/* Resetup the event. */
|
||||||
|
|
||||||
|
usbhost_msc_notifier_setup(usb_msc_disconnect, WORK_USB_MSC_DISCONNECT,
|
||||||
|
sdchar, arg);
|
||||||
|
|
||||||
|
snprintf(mntpnt, sizeof(mntpnt), "%s%c",
|
||||||
|
CONFIG_FRDMK28F_USB_AUTOMOUNT_MOUNTPOINT, sdchar);
|
||||||
|
|
||||||
|
/* Unmount */
|
||||||
|
|
||||||
|
ret = umount2((FAR const char *)mntpnt, MNT_FORCE);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = get_errno();
|
||||||
|
DEBUGASSERT(errcode > 0);
|
||||||
|
|
||||||
|
/* We expect the error to be EBUSY meaning that the volume could
|
||||||
|
* not be unmounted because there are currently reference via open
|
||||||
|
* files or directories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (errcode == EBUSY)
|
||||||
|
{
|
||||||
|
finfo("WARNING: Volume is busy, try again later\n");
|
||||||
|
|
||||||
|
/* Start a timer to retry the umount2 after a delay */
|
||||||
|
|
||||||
|
ret = wd_start(g_umount_tmr[index],
|
||||||
|
MSEC2TICK(CONFIG_FRDMK28F_USB_AUTOMOUNT_UDELAY),
|
||||||
|
unmount_retry_timeout, 1, (uint32_t)index);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ferr("ERROR: wd_start failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Other errors are fatal */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ferr("ERROR: Unmount failed: %d\n", errcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif /* HAVE_USB_AUTOMOUNTER */
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -251,6 +419,9 @@ int k28_usbhost_initialize(void)
|
|||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int ret;
|
int ret;
|
||||||
|
# ifdef HAVE_USB_AUTOMOUNTER
|
||||||
|
int index;
|
||||||
|
# endif
|
||||||
|
|
||||||
/* First, register all of the class drivers needed to support the drivers
|
/* First, register all of the class drivers needed to support the drivers
|
||||||
* that we care about
|
* that we care about
|
||||||
@ -269,6 +440,22 @@ int k28_usbhost_initialize(void)
|
|||||||
#ifdef CONFIG_USBHOST_MSC
|
#ifdef CONFIG_USBHOST_MSC
|
||||||
/* Register the USB host Mass Storage Class */
|
/* Register the USB host Mass Storage Class */
|
||||||
|
|
||||||
|
# ifdef HAVE_USB_AUTOMOUNTER
|
||||||
|
/* Initialize the notifier listener for automount */
|
||||||
|
|
||||||
|
for (index = 0; index < CONFIG_FRDMK28F_USB_AUTOMOUNT_NUM_BLKDEV; index++)
|
||||||
|
{
|
||||||
|
char sdchar = 'a' + index;
|
||||||
|
|
||||||
|
g_umount_tmr[index] = wd_create();
|
||||||
|
|
||||||
|
usbhost_msc_notifier_setup(usb_msc_connect,
|
||||||
|
WORK_USB_MSC_CONNECT, sdchar, (FAR void *)(intptr_t)index);
|
||||||
|
usbhost_msc_notifier_setup(usb_msc_disconnect,
|
||||||
|
WORK_USB_MSC_DISCONNECT, sdchar, (FAR void *)(intptr_t)index);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
ret = usbhost_msc_initialize();
|
ret = usbhost_msc_initialize();
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
|
@ -108,7 +108,17 @@ config USBHOST_MSC
|
|||||||
---help---
|
---help---
|
||||||
Enable support for the mass storage class driver. This also depends on
|
Enable support for the mass storage class driver. This also depends on
|
||||||
NFILE_DESCRIPTORS > 0 && SCHED_WORKQUEUE=y
|
NFILE_DESCRIPTORS > 0 && SCHED_WORKQUEUE=y
|
||||||
|
|
||||||
|
config USBHOST_MSC_NOTIFIER
|
||||||
|
bool "Support USB Mass Storage notifications"
|
||||||
|
default n
|
||||||
|
depends on USBHOST_MSC
|
||||||
|
select WQUEUE_NOTIFIER
|
||||||
|
---help---
|
||||||
|
Enable building of USB MSC notifier logic that will execute a worker
|
||||||
|
function on the low priority work queue when a mass storage device is
|
||||||
|
connected or disconnected.
|
||||||
|
|
||||||
config USBHOST_CDCACM
|
config USBHOST_CDCACM
|
||||||
bool "CDC/ACM support"
|
bool "CDC/ACM support"
|
||||||
default n
|
default n
|
||||||
|
@ -1400,6 +1400,14 @@ static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
|
|||||||
|
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
}
|
}
|
||||||
|
# ifdef CONFIG_USBHOST_MSC_NOTIFIER
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Signal the connect */
|
||||||
|
|
||||||
|
usbhost_msc_notifier_signal(WORK_USB_MSC_CONNECT, priv->sdchar);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
/* Release the semaphore... there is a race condition here.
|
/* Release the semaphore... there is a race condition here.
|
||||||
* Decrementing the reference count and releasing the semaphore
|
* Decrementing the reference count and releasing the semaphore
|
||||||
@ -1409,6 +1417,7 @@ static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
usbhost_givesem(&priv->exclsem);
|
usbhost_givesem(&priv->exclsem);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1848,6 +1857,12 @@ static int usbhost_disconnected(struct usbhost_class_s *usbclass)
|
|||||||
|
|
||||||
DEBUGASSERT(priv != NULL);
|
DEBUGASSERT(priv != NULL);
|
||||||
|
|
||||||
|
# ifdef CONFIG_USBHOST_MSC_NOTIFIER
|
||||||
|
/* Signal the disconnect */
|
||||||
|
|
||||||
|
usbhost_msc_notifier_signal(WORK_USB_MSC_DISCONNECT, priv->sdchar);
|
||||||
|
# endif
|
||||||
|
|
||||||
/* Set an indication to any users of the mass storage device that the
|
/* Set an indication to any users of the mass storage device that the
|
||||||
* device is no longer available.
|
* device is no longer available.
|
||||||
*/
|
*/
|
||||||
@ -2360,4 +2375,98 @@ int usbhost_msc_initialize(void)
|
|||||||
return usbhost_registerclass(&g_storage);
|
return usbhost_registerclass(&g_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef CONFIG_USBHOST_MSC_NOTIFIER
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: usbhost_msc_notifier_setup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set up to perform a callback to the worker function when a mass storage
|
||||||
|
* device is attached.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* worker - The worker function to execute on the low priority work queue
|
||||||
|
* when the event occurs.
|
||||||
|
* event - Currently only USBHOST_MSC_DISCONNECT and USBHOST_MSC_CONNECT
|
||||||
|
* sdchar - sdchar of the connected or disconnected block device
|
||||||
|
* arg - A user-defined argument that will be available to the worker
|
||||||
|
* function when it runs.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* > 0 - The notification is in place. The returned value is a key that
|
||||||
|
* may be used later in a call to
|
||||||
|
* usbmsc_attach_notifier_teardown().
|
||||||
|
* == 0 - Not used.
|
||||||
|
* < 0 - An unexpected error occurred and no notification will occur. The
|
||||||
|
* returned value is a negated errno value that indicates the
|
||||||
|
* nature of the failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int usbhost_msc_notifier_setup(worker_t worker, uint8_t event, char sdchar,
|
||||||
|
FAR void *arg)
|
||||||
|
{
|
||||||
|
struct work_notifier_s info;
|
||||||
|
|
||||||
|
DEBUGASSERT(worker != NULL);
|
||||||
|
|
||||||
|
info.evtype = event;
|
||||||
|
info.qid = LPWORK;
|
||||||
|
info.qualifier = (FAR void *)(uintptr_t)sdchar;
|
||||||
|
info.arg = arg;
|
||||||
|
info.worker = worker;
|
||||||
|
|
||||||
|
return work_notifier_setup(&info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: usbhost_msc_notifier_teardown
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Eliminate an USB MSC notification previously setup by
|
||||||
|
* usbhost_msc_notifier_setup().
|
||||||
|
* This function should only be called if the notification should be
|
||||||
|
* aborted prior to the notification. The notification will automatically
|
||||||
|
* be torn down after the notification.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* key - The key value returned from a previous call to
|
||||||
|
* usbhost_msc_notifier_setup().
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||||
|
* any failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int usbhost_msc_notifier_teardown(int key)
|
||||||
|
{
|
||||||
|
/* This is just a simple wrapper around work_notifier_teardown(). */
|
||||||
|
|
||||||
|
return work_notifier_teardown(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: usbhost_msc_notifier_signal
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* An USB mass storage device has been connected or disconnected.
|
||||||
|
* Signal all threads.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* event - Currently only USBHOST_MSC_DISCONNECT and USBHOST_MSC_CONNECT
|
||||||
|
* sdchar - sdchar of the connected or disconnected block device
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void usbhost_msc_notifier_signal(uint8_t event, char sdchar)
|
||||||
|
{
|
||||||
|
work_notifier_signal(event, (FAR void *)(uintptr_t)sdchar);
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif /* CONFIG_USBHOST_MSC_NOTIFIER */
|
||||||
|
|
||||||
#endif /* CONFIG_USBHOST && !CONFIG_USBHOST_BULK_DISABLE && !CONFIG_DISABLE_MOUNTPOINT */
|
#endif /* CONFIG_USBHOST && !CONFIG_USBHOST_BULK_DISABLE && !CONFIG_DISABLE_MOUNTPOINT */
|
||||||
|
@ -39,6 +39,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_USBHOST_MSC_NOTIFIER
|
||||||
|
# include <nuttx/wqueue.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nuttx/usb/usbhost_devaddr.h>
|
#include <nuttx/usb/usbhost_devaddr.h>
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
@ -1014,6 +1018,78 @@ int usbhost_hub_initialize(void);
|
|||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
int usbhost_msc_initialize(void);
|
int usbhost_msc_initialize(void);
|
||||||
|
|
||||||
|
# ifdef CONFIG_USBHOST_MSC_NOTIFIER
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: usbhost_msc_notifier_setup
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set up to perform a callback to the worker function when a mass storage
|
||||||
|
* device is attached.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* worker - The worker function to execute on the low priority work queue
|
||||||
|
* when the event occurs.
|
||||||
|
* event - Only WORK_USB_MSC_CONNECT and WORK_USB_MSC_DISCONNECT
|
||||||
|
* sdchar - sdchar of the connected or disconnected block device
|
||||||
|
* arg - A user-defined argument that will be available to the worker
|
||||||
|
* function when it runs.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* > 0 - The notification is in place. The returned value is a key that
|
||||||
|
* may be used later in a call to
|
||||||
|
* usbmsc_attach_notifier_teardown().
|
||||||
|
* == 0 - Not used.
|
||||||
|
* < 0 - An unexpected error occurred and no notification will occur. The
|
||||||
|
* returned value is a negated errno value that indicates the
|
||||||
|
* nature of the failure.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
int usbhost_msc_notifier_setup(worker_t worker, uint8_t event, char sdchar,
|
||||||
|
FAR void *arg);
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: usbhost_msc_notifier_teardown
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Eliminate an USB MSC notification previously setup by
|
||||||
|
* usbhost_msc_notifier_setup().
|
||||||
|
* This function should only be called if the notification should be
|
||||||
|
* aborted prior to the notification. The notification will automatically
|
||||||
|
* be torn down after the notification.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* key - The key value returned from a previous call to
|
||||||
|
* usbhost_msc_notifier_setup().
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||||
|
* any failure.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
int usbhost_msc_notifier_teardown(int key);
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: usbhost_msc_notifier_signal
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* An USB mass storage device has been connected or disconnected.
|
||||||
|
* Signal all threads.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* event - Currently only USBHOST_MSC_DISCONNECT and USBHOST_MSC_CONNECT
|
||||||
|
* sdchar - sdchar of the connected or disconnected block device
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
void usbhost_msc_notifier_signal(uint8_t event, char sdchar);
|
||||||
|
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_USBHOST_CDCACM
|
#ifdef CONFIG_USBHOST_CDCACM
|
||||||
|
@ -273,15 +273,17 @@ struct work_s
|
|||||||
|
|
||||||
enum work_evtype_e
|
enum work_evtype_e
|
||||||
{
|
{
|
||||||
WORK_IOB_AVAIL = 1, /* Notify availability of an IOB */
|
WORK_IOB_AVAIL = 1, /* Notify availability of an IOB */
|
||||||
WORK_NET_DOWN, /* Notify that the network is down */
|
WORK_NET_DOWN, /* Notify that the network is down */
|
||||||
WORK_TCP_READAHEAD, /* Notify that TCP read-ahead data is available */
|
WORK_TCP_READAHEAD, /* Notify that TCP read-ahead data is available */
|
||||||
WORK_TCP_WRITEBUFFER, /* Notify that TCP write buffer is empty */
|
WORK_TCP_WRITEBUFFER, /* Notify that TCP write buffer is empty */
|
||||||
WORK_TCP_DISCONNECT, /* Notify loss of TCP connection */
|
WORK_TCP_DISCONNECT, /* Notify loss of TCP connection */
|
||||||
WORK_UDP_READAHEAD, /* Notify that UDP read-ahead data is available */
|
WORK_UDP_READAHEAD, /* Notify that UDP read-ahead data is available */
|
||||||
WORK_UDP_WRITEBUFFER, /* Notify that UDP write buffer is empty */
|
WORK_UDP_WRITEBUFFER, /* Notify that UDP write buffer is empty */
|
||||||
WORK_NETLINK_RESPONSE, /* Notify that Netlink response is available */
|
WORK_NETLINK_RESPONSE, /* Notify that Netlink response is available */
|
||||||
WORK_CAN_READAHEAD /* Notify that CAN read-ahead data is available */
|
WORK_CAN_READAHEAD, /* Notify that CAN read-ahead data is available */
|
||||||
|
WORK_USB_MSC_CONNECT, /* Notify that an USB MSC connect occured */
|
||||||
|
WORK_USB_MSC_DISCONNECT /* Notify that an USB MSC connect occured */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This structure describes one notification and is provided as input to
|
/* This structure describes one notification and is provided as input to
|
||||||
|
Loading…
x
Reference in New Issue
Block a user