Commit e1c7e324 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Linus Torvalds

dma-mapping: always provide the dma_map_ops based implementation

Move the generic implementation to <linux/dma-mapping.h> now that all
architectures support it and remove the HAVE_DMA_ATTR Kconfig symbol now
that everyone supports them.

[valentinrothberg@gmail.com: remove leftovers in Kconfig]
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
Cc: Chris Metcalf <cmetcalf@ezchip.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Cc: Helge Deller <deller@gmx.de>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
Cc: Ley Foon Tan <lftan@altera.com>
Cc: Mark Salter <msalter@redhat.com>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Steven Miao <realmz6@gmail.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Joerg Roedel <jroedel@suse.de>
Cc: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarValentin Rothberg <valentinrothberg@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent bd38118f
......@@ -951,16 +951,6 @@ to "Closing".
alignment constraints (e.g. the alignment constraints about 64-bit
objects).
3) Supporting multiple types of IOMMUs
If your architecture needs to support multiple types of IOMMUs, you
can use include/linux/asm-generic/dma-mapping-common.h. It's a
library to support the DMA API with multiple types of IOMMUs. Lots
of architectures (x86, powerpc, sh, alpha, ia64, microblaze and
sparc) use it. Choose one to see how it can be used. If you need to
support multiple types of IOMMUs in a single system, the example of
x86 or powerpc helps.
Closing
This document, and the API itself, would not be in its current
......
#
# Feature name: dma_map_attrs
# Kconfig: HAVE_DMA_ATTRS
# description: arch provides dma_*map*_attrs() APIs
#
-----------------------
| arch |status|
-----------------------
| alpha: | ok |
| arc: | TODO |
| arm: | ok |
| arm64: | ok |
| avr32: | TODO |
| blackfin: | TODO |
| c6x: | TODO |
| cris: | TODO |
| frv: | TODO |
| h8300: | ok |
| hexagon: | ok |
| ia64: | ok |
| m32r: | TODO |
| m68k: | TODO |
| metag: | TODO |
| microblaze: | ok |
| mips: | ok |
| mn10300: | TODO |
| nios2: | TODO |
| openrisc: | ok |
| parisc: | TODO |
| powerpc: | ok |
| s390: | ok |
| score: | TODO |
| sh: | ok |
| sparc: | ok |
| tile: | ok |
| um: | TODO |
| unicore32: | ok |
| x86: | ok |
| xtensa: | TODO |
-----------------------
......@@ -205,9 +205,6 @@ config HAVE_NMI_WATCHDOG
config HAVE_ARCH_TRACEHOOK
bool
config HAVE_DMA_ATTRS
bool
config HAVE_DMA_CONTIGUOUS
bool
......
......@@ -9,7 +9,6 @@ config ALPHA
select HAVE_OPROFILE
select HAVE_PCSPKR_PLATFORM
select HAVE_PERF_EVENTS
select HAVE_DMA_ATTRS
select VIRT_TO_BUS
select GENERIC_IRQ_PROBE
select AUTO_IRQ_AFFINITY if SMP
......
......@@ -10,8 +10,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return dma_ops;
}
#include <asm-generic/dma-mapping-common.h>
#define dma_cache_sync(dev, va, size, dir) ((void)0)
#endif /* _ALPHA_DMA_MAPPING_H */
......@@ -38,7 +38,6 @@ config ARC
select OF_EARLY_FLATTREE
select PERF_USE_VMALLOC
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DMA_ATTRS
config TRACE_IRQFLAGS_SUPPORT
def_bool y
......
......@@ -18,6 +18,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &arc_dma_ops;
}
#include <asm-generic/dma-mapping-common.h>
#endif
......@@ -47,7 +47,6 @@ config ARM
select HAVE_C_RECORDMCOUNT
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
select HAVE_DMA_CONTIGUOUS if MMU
select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) && !CPU_ENDIAN_BE32 && MMU
select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU
......
......@@ -41,13 +41,6 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
#define HAVE_ARCH_DMA_SUPPORTED 1
extern int dma_supported(struct device *dev, u64 mask);
/*
* Note that while the generic code provides dummy dma_{alloc,free}_noncoherent
* implementations, we don't provide a dma_cache_sync function so drivers using
* this API are highlighted with build warnings.
*/
#include <asm-generic/dma-mapping-common.h>
#ifdef __arch_page_to_dma
#error Please update to __arch_pfn_to_dma
#endif
......
......@@ -64,7 +64,6 @@ config ARM64
select HAVE_DEBUG_BUGVERBOSE
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
select HAVE_EFFICIENT_UNALIGNED_ACCESS
......
......@@ -64,8 +64,6 @@ static inline bool is_device_dma_coherent(struct device *dev)
return dev->archdata.dma_coherent;
}
#include <asm-generic/dma-mapping-common.h>
static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
{
return (dma_addr_t)paddr;
......
......@@ -7,7 +7,6 @@ config AVR32
select HAVE_OPROFILE
select HAVE_KPROBES
select VIRT_TO_BUS
select HAVE_DMA_ATTRS
select GENERIC_IRQ_PROBE
select GENERIC_ATOMIC64
select HARDIRQS_SW_RESEND
......
......@@ -11,6 +11,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &avr32_dma_ops;
}
#include <asm-generic/dma-mapping-common.h>
#endif /* __ASM_AVR32_DMA_MAPPING_H */
......@@ -14,7 +14,6 @@ config BLACKFIN
def_bool y
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_ATTRS
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER
......
......@@ -43,6 +43,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &bfin_dma_ops;
}
#include <asm-generic/dma-mapping-common.h>
#endif /* _BLACKFIN_DMA_MAPPING_H */
......@@ -18,7 +18,6 @@ config C6X
select GENERIC_CLOCKEVENTS
select MODULES_USE_ELF_RELA
select ARCH_NO_COHERENT_DMA_MMAP
select HAVE_DMA_ATTRS
config MMU
def_bool n
......
......@@ -24,8 +24,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &c6x_dma_ops;
}
#include <asm-generic/dma-mapping-common.h>
extern void coherent_mem_init(u32 start, u32 size);
void *c6x_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t gfp, struct dma_attrs *attrs);
......
......@@ -54,7 +54,6 @@ config CRIS
select GENERIC_ATOMIC64
select HAVE_UID16
select VIRT_TO_BUS
select HAVE_DMA_ATTRS
select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_IOMAP
......
......@@ -16,8 +16,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
}
#endif
#include <asm-generic/dma-mapping-common.h>
static inline void
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
......
......@@ -16,7 +16,6 @@ config FRV
select OLD_SIGACTION
select HAVE_DEBUG_STACKOVERFLOW
select ARCH_NO_COHERENT_DMA_MMAP
select HAVE_DMA_ATTRS
config ZONE_DMA
bool
......
......@@ -21,6 +21,4 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
flush_write_buffers();
}
#include <asm-generic/dma-mapping-common.h>
#endif /* _ASM_DMA_MAPPING_H */
......@@ -15,7 +15,6 @@ config H8300
select OF_IRQ
select OF_EARLY_FLATTREE
select HAVE_MEMBLOCK
select HAVE_DMA_ATTRS
select CLKSRC_OF
select H8300_TMR8
......
......@@ -8,6 +8,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &h8300_dma_map_ops;
}
#include <asm-generic/dma-mapping-common.h>
#endif
......@@ -27,7 +27,6 @@ config HEXAGON
select GENERIC_CLOCKEVENTS_BROADCAST
select MODULES_USE_ELF_RELA
select GENERIC_CPU_DEVICES
select HAVE_DMA_ATTRS
---help---
Qualcomm Hexagon is a processor architecture designed for high
performance and low power across a wide variety of applications.
......
......@@ -49,8 +49,6 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_handle);
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
#include <asm-generic/dma-mapping-common.h>
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
......
......@@ -25,7 +25,6 @@ config IA64
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE if (!ITANIUM)
select HAVE_FUNCTION_TRACER
select HAVE_DMA_ATTRS
select TTY
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
......
......@@ -25,8 +25,6 @@ extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
#define get_dma_ops(dev) platform_dma_get_ops(dev)
#include <asm-generic/dma-mapping-common.h>
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
......
......@@ -23,7 +23,6 @@ config M68K
select MODULES_USE_ELF_RELA
select OLD_SIGSUSPEND3
select OLD_SIGACTION
select HAVE_DMA_ATTRS
config RWSEM_GENERIC_SPINLOCK
bool
......
......@@ -8,8 +8,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &m68k_dma_ops;
}
#include <asm-generic/dma-mapping-common.h>
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir)
{
......
......@@ -29,7 +29,6 @@ config METAG
select OF
select OF_EARLY_FLATTREE
select SPARSE_IRQ
select HAVE_DMA_ATTRS
config STACKTRACE_SUPPORT
def_bool y
......
......@@ -8,8 +8,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &metag_dma_ops;
}
#include <asm-generic/dma-mapping-common.h>
/*
* dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to
* do any flushing here.
......
......@@ -19,7 +19,6 @@ config MICROBLAZE
select HAVE_ARCH_KGDB
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER
......
......@@ -44,8 +44,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &dma_direct_ops;
}
#include <asm-generic/dma-mapping-common.h>
static inline void __dma_sync(unsigned long paddr,
size_t size, enum dma_data_direction direction)
{
......
......@@ -31,7 +31,6 @@ config MIPS
select RTC_LIB if !MACH_LOONGSON64
select GENERIC_ATOMIC64 if !64BIT
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select HAVE_DMA_ATTRS
select HAVE_DMA_CONTIGUOUS
select HAVE_DMA_API_DEBUG
select GENERIC_IRQ_PROBE
......
......@@ -29,8 +29,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
static inline void dma_mark_clean(void *addr, size_t size) {}
#include <asm-generic/dma-mapping-common.h>
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
......
......@@ -15,7 +15,6 @@ config MN10300
select OLD_SIGACTION
select HAVE_DEBUG_STACKOVERFLOW
select ARCH_NO_COHERENT_DMA_MMAP
select HAVE_DMA_ATTRS
config AM33_2
def_bool n
......
......@@ -28,6 +28,4 @@ void dma_cache_sync(void *vaddr, size_t size,
mn10300_dcache_flush_inv();
}
#include <asm-generic/dma-mapping-common.h>
#endif
......@@ -16,7 +16,6 @@ config NIOS2
select SOC_BUS
select SPARSE_IRQ
select USB_ARCH_HAS_HCD if USB_SUPPORT
select HAVE_DMA_ATTRS
config GENERIC_CSUM
def_bool y
......
......@@ -29,9 +29,6 @@ config OPENRISC
config MMU
def_bool y
config HAVE_DMA_ATTRS
def_bool y
config RWSEM_GENERIC_SPINLOCK
def_bool y
......
......@@ -42,6 +42,4 @@ static inline int dma_supported(struct device *dev, u64 dma_mask)
return dma_mask == DMA_BIT_MASK(32);
}
#include <asm-generic/dma-mapping-common.h>
#endif /* __ASM_OPENRISC_DMA_MAPPING_H */
......@@ -30,7 +30,6 @@ config PARISC
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_ARCH_AUDITSYSCALL
select ARCH_NO_COHERENT_DMA_MMAP
select HAVE_DMA_ATTRS
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
......
......@@ -83,6 +83,4 @@ struct parisc_device;
void * sba_get_iommu(struct parisc_device *dev);
#endif
#include <asm-generic/dma-mapping-common.h>
#endif
......@@ -108,7 +108,6 @@ config PPC
select HAVE_ARCH_TRACEHOOK
select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_OPROFILE
select HAVE_DEBUG_KMEMLEAK
......
......@@ -125,8 +125,6 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
#define HAVE_ARCH_DMA_SET_MASK 1
extern int dma_set_mask(struct device *dev, u64 dma_mask);
#include <asm-generic/dma-mapping-common.h>
extern int __dma_set_mask(struct device *dev, u64 dma_mask);
extern u64 __dma_get_required_mask(struct device *dev);
......
......@@ -579,7 +579,6 @@ config QDIO
menuconfig PCI
bool "PCI support"
select HAVE_DMA_ATTRS
select PCI_MSI
select IOMMU_SUPPORT
help
......
......@@ -23,8 +23,6 @@ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
{
}
#include <asm-generic/dma-mapping-common.h>
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
......
......@@ -11,7 +11,6 @@ config SUPERH
select HAVE_GENERIC_DMA_COHERENT
select HAVE_ARCH_TRACEHOOK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
select HAVE_PERF_EVENTS
select HAVE_DEBUG_BUGVERBOSE
select ARCH_HAVE_CUSTOM_GPIO_H
......
......@@ -11,8 +11,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
#define DMA_ERROR_CODE 0
#include <asm-generic/dma-mapping-common.h>
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir);
......
......@@ -26,7 +26,6 @@ config SPARC
select RTC_CLASS
select RTC_DRV_M48T59
select RTC_SYSTOHC
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_ARCH_JUMP_LABEL if SPARC64
select GENERIC_IRQ_SHOW
......
......@@ -37,6 +37,4 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return dma_ops;
}
#include <asm-generic/dma-mapping-common.h>
#endif
......@@ -5,7 +5,6 @@ config TILE
def_bool y
select HAVE_PERF_EVENTS
select USE_PMC if PERF_EVENTS
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_KVM if !TILEGX
select GENERIC_FIND_FIRST_BIT
......
......@@ -73,9 +73,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
}
#define HAVE_ARCH_DMA_SET_MASK 1
#include <asm-generic/dma-mapping-common.h>
int dma_set_mask(struct device *dev, u64 mask);
/*
......
......@@ -5,7 +5,6 @@ config UNICORE32
select ARCH_MIGHT_HAVE_PC_SERIO
select HAVE_MEMBLOCK
select HAVE_GENERIC_DMA_COHERENT
select HAVE_DMA_ATTRS
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select GENERIC_ATOMIC64
......
......@@ -28,8 +28,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &swiotlb_dma_map_ops;
}
#include <asm-generic/dma-mapping-common.h>
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (dev && dev->dma_mask)
......
......@@ -100,7 +100,6 @@ config X86
select HAVE_DEBUG_KMEMLEAK
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
select HAVE_DYNAMIC_FTRACE_WITH_REGS
......
......@@ -46,8 +46,6 @@ bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp);
#define HAVE_ARCH_DMA_SUPPORTED 1
extern int dma_supported(struct device *hwdev, u64 mask);
#include <asm-generic/dma-mapping-common.h>
extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_addr, gfp_t flag,
struct dma_attrs *attrs);
......
......@@ -15,7 +15,6 @@ config XTENSA
select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
select HAVE_DMA_API_DEBUG
select HAVE_DMA_ATTRS
select HAVE_FUNCTION_TRACER
select HAVE_FUTEX_CMPXCHG if !MMU
select HAVE_IRQ_TIME_ACCOUNTING
......
......@@ -30,8 +30,6 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return &xtensa_dma_map_ops;
}
#include <asm-generic/dma-mapping-common.h>
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction);
......
......@@ -82,13 +82,13 @@ config DRM_TTM
config DRM_GEM_CMA_HELPER
bool
depends on DRM && HAVE_DMA_ATTRS
depends on DRM
help
Choose this if you need the GEM CMA helper functions
config DRM_KMS_CMA_HELPER
bool
depends on DRM && HAVE_DMA_ATTRS
depends on DRM
select DRM_GEM_CMA_HELPER
select DRM_KMS_FB_HELPER
select FB_SYS_FILLRECT
......
......@@ -5,7 +5,7 @@ config DRM_IMX
select VIDEOMODE_HELPERS
select DRM_GEM_CMA_HELPER
select DRM_KMS_CMA_HELPER
depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM) && HAVE_DMA_ATTRS
depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM)
depends on IMX_IPUV3_CORE
help
enable i.MX graphics support
......
config DRM_RCAR_DU
tristate "DRM Support for R-Car Display Unit"
depends on DRM && ARM && HAVE_DMA_ATTRS && OF
depends on DRM && ARM && OF
depends on ARCH_SHMOBILE || COMPILE_TEST
select DRM_KMS_HELPER
select DRM_KMS_CMA_HELPER
......
config DRM_SHMOBILE
tristate "DRM Support for SH Mobile"
depends on DRM && ARM && HAVE_DMA_ATTRS
depends on DRM && ARM
depends on ARCH_SHMOBILE || COMPILE_TEST
depends on FB_SH_MOBILE_MERAM || !FB_SH_MOBILE_MERAM
select BACKLIGHT_CLASS_DEVICE
......
config DRM_STI
tristate "DRM Support for STMicroelectronics SoC stiH41x Series"
depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM) && HAVE_DMA_ATTRS
depends on DRM && (SOC_STIH415 || SOC_STIH416 || ARCH_MULTIPLATFORM)
select RESET_CONTROLLER
select DRM_KMS_HELPER
select DRM_GEM_CMA_HELPER
......
config DRM_TILCDC
tristate "DRM Support for TI LCDC Display Controller"
depends on DRM && OF && ARM && HAVE_DMA_ATTRS
depends on DRM && OF && ARM
select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER
select DRM_KMS_CMA_HELPER
......
config DRM_VC4
tristate "Broadcom VC4 Graphics"
depends on ARCH_BCM2835 || COMPILE_TEST
depends on DRM && HAVE_DMA_ATTRS
depends on DRM
select DRM_KMS_HELPER
select DRM_KMS_CMA_HELPER
select DRM_GEM_CMA_HELPER
......
......@@ -216,7 +216,6 @@ config VIDEO_STI_BDISP
tristate "STMicroelectronics BDISP 2D blitter driver"
depends on VIDEO_DEV && VIDEO_V4L2
depends on ARCH_STI || COMPILE_TEST
depends on HAVE_DMA_ATTRS
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
help
......