Skip to content
Snippets Groups Projects
Commit 344ac148 authored by Paul Mundt's avatar Paul Mundt
Browse files

Merge branch 'master' of...

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into sh/urgent
parents 8ac5ba61 0143832c
No related branches found
No related tags found
No related merge requests found
Showing
with 375 additions and 58 deletions
What: /proc/<pid>/oom_adj
When: August 2012
Why: /proc/<pid>/oom_adj allows userspace to influence the oom killer's
badness heuristic used to determine which task to kill when the kernel
is out of memory.
The badness heuristic has since been rewritten since the introduction of
this tunable such that its meaning is deprecated. The value was
implemented as a bitshift on a score generated by the badness()
function that did not have any precise units of measure. With the
rewrite, the score is given as a proportion of available memory to the
task allocating pages, so using a bitshift which grows the score
exponentially is, thus, impossible to tune with fine granularity.
A much more powerful interface, /proc/<pid>/oom_score_adj, was
introduced with the oom killer rewrite that allows users to increase or
decrease the badness() score linearly. This interface will replace
/proc/<pid>/oom_adj.
A warning will be emitted to the kernel log if an application uses this
deprecated interface. After it is printed once, future warnings will be
suppressed until the kernel is rebooted.
......@@ -16,7 +16,7 @@ you can do so by typing:
As of the Linux 2.6.10 kernel, it is now possible to change the
IO scheduler for a given block device on the fly (thus making it possible,
for instance, to set the CFQ scheduler for the system default, but
set a specific device to use the anticipatory or noop schedulers - which
set a specific device to use the deadline or noop schedulers - which
can improve that device's throughput).
To set a specific scheduler, simply do this:
......@@ -31,7 +31,7 @@ a "cat /sys/block/DEV/queue/scheduler" - the list of valid names
will be displayed, with the currently selected scheduler in brackets:
# cat /sys/block/hda/queue/scheduler
noop anticipatory deadline [cfq]
# echo anticipatory > /sys/block/hda/queue/scheduler
noop deadline [cfq]
# echo deadline > /sys/block/hda/queue/scheduler
# cat /sys/block/hda/queue/scheduler
noop [anticipatory] deadline cfq
noop [deadline] cfq
......@@ -794,17 +794,6 @@ designed.
Roadmap:
2.6.37 Remove experimental tag from mount option
=> should be roughly 6 months after initial merge
=> enough time to:
=> gain confidence and fix problems reported by early
adopters (a.k.a. guinea pigs)
=> address worst performance regressions and undesired
behaviours
=> start tuning/optimising code for parallelism
=> start tuning/optimising algorithms consuming
excessive CPU time
2.6.39 Switch default mount option to use delayed logging
=> should be roughly 12 months after initial merge
=> enough time to shake out remaining problems before next round of
......
......@@ -706,7 +706,7 @@ and is between 256 and 4096 characters. It is defined in the file
arch/x86/kernel/cpu/cpufreq/elanfreq.c.
elevator= [IOSCHED]
Format: {"anticipatory" | "cfq" | "deadline" | "noop"}
Format: {"cfq" | "deadline" | "noop"}
See Documentation/block/as-iosched.txt and
Documentation/block/deadline-iosched.txt for details.
......
......@@ -60,15 +60,18 @@ Hardware accelerated blink of LEDs
Some LEDs can be programmed to blink without any CPU interaction. To
support this feature, a LED driver can optionally implement the
blink_set() function (see <linux/leds.h>). If implemented, triggers can
attempt to use it before falling back to software timers. The blink_set()
function should return 0 if the blink setting is supported, or -EINVAL
otherwise, which means that LED blinking will be handled by software.
The blink_set() function should choose a user friendly blinking
value if it is called with *delay_on==0 && *delay_off==0 parameters. In
this case the driver should give back the chosen value through delay_on
and delay_off parameters to the leds subsystem.
blink_set() function (see <linux/leds.h>). To set an LED to blinking,
however, it is better to use use the API function led_blink_set(),
as it will check and implement software fallback if necessary.
To turn off blinking again, use the API function led_brightness_set()
as that will not just set the LED brightness but also stop any software
timers that may have been required for blinking.
The blink_set() function should choose a user friendly blinking value
if it is called with *delay_on==0 && *delay_off==0 parameters. In this
case the driver should give back the chosen value through delay_on and
delay_off parameters to the leds subsystem.
Setting the brightness to zero with brightness_set() callback function
should completely turn off the LED and cancel the previously programmed
......
Kernel driver for lp5521
========================
* National Semiconductor LP5521 led driver chip
* Datasheet: http://www.national.com/pf/LP/LP5521.html
Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
Description
-----------
LP5521 can drive up to 3 channels. Leds can be controlled directly via
the led class control interface. Channels have generic names:
lp5521:channelx, where x is 0 .. 2
All three channels can be also controlled using the engine micro programs.
More details of the instructions can be found from the public data sheet.
Control interface for the engines:
x is 1 .. 3
enginex_mode : disabled, load, run
enginex_load : store program (visible only in engine load mode)
Example (start to blink the channel 2 led):
cd /sys/class/leds/lp5521:channel2/device
echo "load" > engine3_mode
echo "037f4d0003ff6000" > engine3_load
echo "run" > engine3_mode
stop the engine:
echo "disabled" > engine3_mode
sysfs contains a selftest entry.
The test communicates with the chip and checks that
the clock mode is automatically set to the requested one.
Each channel has its own led current settings.
/sys/class/leds/lp5521:channel0/led_current - RW
/sys/class/leds/lp5521:channel0/max_current - RO
Format: 10x mA i.e 10 means 1.0 mA
example platform data:
Note: chan_nr can have values between 0 and 2.
static struct lp5521_led_config lp5521_led_config[] = {
{
.chan_nr = 0,
.led_current = 50,
.max_current = 130,
}, {
.chan_nr = 1,
.led_current = 0,
.max_current = 130,
}, {
.chan_nr = 2,
.led_current = 0,
.max_current = 130,
}
};
static int lp5521_setup(void)
{
/* setup HW resources */
}
static void lp5521_release(void)
{
/* Release HW resources */
}
static void lp5521_enable(bool state)
{
/* Control of chip enable signal */
}
static struct lp5521_platform_data lp5521_platform_data = {
.led_config = lp5521_led_config,
.num_channels = ARRAY_SIZE(lp5521_led_config),
.clock_mode = LP5521_CLOCK_EXT,
.setup_resources = lp5521_setup,
.release_resources = lp5521_release,
.enable = lp5521_enable,
};
If the current is set to 0 in the platform data, that channel is
disabled and it is not visible in the sysfs.
Kernel driver for lp5523
========================
* National Semiconductor LP5523 led driver chip
* Datasheet: http://www.national.com/pf/LP/LP5523.html
Authors: Mathias Nyman, Yuri Zaporozhets, Samu Onkalo
Contact: Samu Onkalo (samu.p.onkalo-at-nokia.com)
Description
-----------
LP5523 can drive up to 9 channels. Leds can be controlled directly via
the led class control interface. Channels have generic names:
lp5523:channelx where x is 0...8
The chip provides 3 engines. Each engine can control channels without
interaction from the main CPU. Details of the micro engine code can be found
from the public data sheet. Leds can be muxed to different channels.
Control interface for the engines:
x is 1 .. 3
enginex_mode : disabled, load, run
enginex_load : microcode load (visible only in load mode)
enginex_leds : led mux control (visible only in load mode)
cd /sys/class/leds/lp5523:channel2/device
echo "load" > engine3_mode
echo "9d80400004ff05ff437f0000" > engine3_load
echo "111111111" > engine3_leds
echo "run" > engine3_mode
sysfs contains a selftest entry. It measures each channel
voltage level and checks if it looks reasonable. If the level is too high,
the led is missing; if the level is too low, there is a short circuit.
Selftest uses always the current from the platform data.
Each channel contains led current settings.
/sys/class/leds/lp5523:channel2/led_current - RW
/sys/class/leds/lp5523:channel2/max_current - RO
Format: 10x mA i.e 10 means 1.0 mA
Example platform data:
Note - chan_nr can have values between 0 and 8.
static struct lp5523_led_config lp5523_led_config[] = {
{
.chan_nr = 0,
.led_current = 50,
.max_current = 130,
},
...
}, {
.chan_nr = 8,
.led_current = 50,
.max_current = 130,
}
};
static int lp5523_setup(void)
{
/* Setup HW resources */
}
static void lp5523_release(void)
{
/* Release HW resources */
}
static void lp5523_enable(bool state)
{
/* Control chip enable signal */
}
static struct lp5523_platform_data lp5523_platform_data = {
.led_config = lp5523_led_config,
.num_channels = ARRAY_SIZE(lp5523_led_config),
.clock_mode = LP5523_CLOCK_EXT,
.setup_resources = lp5523_setup,
.release_resources = lp5523_release,
.enable = lp5523_enable,
};
......@@ -20,6 +20,15 @@ ip_no_pmtu_disc - BOOLEAN
min_pmtu - INTEGER
default 562 - minimum discovered Path MTU
route/max_size - INTEGER
Maximum number of routes allowed in the kernel. Increase
this when using large numbers of interfaces and/or routes.
neigh/default/gc_thresh3 - INTEGER
Maximum number of neighbor entries allowed. Increase this
when using large numbers of interfaces and when communicating
with large numbers of directly-connected peers.
mtu_expires - INTEGER
Time, in seconds, that cached PMTU information is kept.
......
......@@ -21,8 +21,8 @@ three rotations, respectively, to balance the tree), with slightly slower
To quote Linux Weekly News:
There are a number of red-black trees in use in the kernel.
The anticipatory, deadline, and CFQ I/O schedulers all employ
rbtrees to track requests; the packet CD/DVD driver does the same.
The deadline and CFQ I/O schedulers employ rbtrees to
track requests; the packet CD/DVD driver does the same.
The high-resolution timer code uses an rbtree to organize outstanding
timer requests. The ext3 filesystem tracks directory entries in a
red-black tree. Virtual memory areas (VMAs) are tracked with red-black
......
......@@ -28,6 +28,7 @@ show up in /proc/sys/kernel:
- core_uses_pid
- ctrl-alt-del
- dentry-state
- dmesg_restrict
- domainname
- hostname
- hotplug
......@@ -213,6 +214,19 @@ to decide what to do with it.
==============================================================
dmesg_restrict:
This toggle indicates whether unprivileged users are prevented from using
dmesg(8) to view messages from the kernel's log buffer. When
dmesg_restrict is set to (0) there are no restrictions. When
dmesg_restrict is set set to (1), users must have CAP_SYS_ADMIN to use
dmesg(8).
The kernel config option CONFIG_SECURITY_DMESG_RESTRICT sets the default
value of dmesg_restrict.
==============================================================
domainname & hostname:
These files can be used to set the NIS/YP domainname and the
......
......@@ -161,7 +161,7 @@ M: Greg Kroah-Hartman <gregkh@suse.de>
L: linux-serial@vger.kernel.org
W: http://serial.sourceforge.net
S: Maintained
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
F: drivers/serial/8250*
F: include/linux/serial_8250.h
......@@ -5676,7 +5676,7 @@ S: Maintained
STAGING SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@suse.de>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-next-2.6.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git
L: devel@driverdev.osuosl.org
S: Maintained
F: drivers/staging/
......@@ -5910,7 +5910,7 @@ S: Maintained
TTY LAYER
M: Greg Kroah-Hartman <gregkh@suse.de>
S: Maintained
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
F: drivers/char/tty_*
F: drivers/serial/serial_core.c
F: include/linux/serial_core.h
......@@ -6233,7 +6233,7 @@ USB SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@suse.de>
L: linux-usb@vger.kernel.org
W: http://www.linux-usb.org
T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git
S: Supported
F: Documentation/usb/
F: drivers/net/usb/
......@@ -6598,14 +6598,14 @@ F: drivers/platform/x86
XEN PCI SUBSYSTEM
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: xen-devel@lists.xensource.com
L: xen-devel@lists.xensource.com (moderated for non-subscribers)
S: Supported
F: arch/x86/pci/*xen*
F: drivers/pci/*xen*
XEN SWIOTLB SUBSYSTEM
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: xen-devel@lists.xensource.com
L: xen-devel@lists.xensource.com (moderated for non-subscribers)
S: Supported
F: arch/x86/xen/*swiotlb*
F: drivers/xen/*swiotlb*
......@@ -6613,7 +6613,7 @@ F: drivers/xen/*swiotlb*
XEN HYPERVISOR INTERFACE
M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: xen-devel@lists.xen.org
L: xen-devel@lists.xensource.com (moderated for non-subscribers)
L: virtualization@lists.osdl.org
S: Supported
F: arch/x86/xen/
......
......@@ -6,7 +6,7 @@ config ARM
select HAVE_MEMBLOCK
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
select GENERIC_ATOMIC64 if (!CPU_32v6K)
select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI)
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_ARCH_KGDB
select HAVE_KPROBES if (!XIP_KERNEL)
......
......@@ -251,15 +251,16 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
/*
* Set priority on all interrupts.
* Set priority on all global interrupts.
*/
for (i = 0; i < max_irq; i += 4)
for (i = 32; i < max_irq; i += 4)
writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
/*
* Disable all interrupts.
* Disable all interrupts. Leave the PPI and SGIs alone
* as these enables are banked registers.
*/
for (i = 0; i < max_irq; i += 32)
for (i = 32; i < max_irq; i += 32)
writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
/*
......@@ -277,11 +278,30 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
{
void __iomem *dist_base;
int i;
if (gic_nr >= MAX_GIC_NR)
BUG();
dist_base = gic_data[gic_nr].dist_base;
BUG_ON(!dist_base);
gic_data[gic_nr].cpu_base = base;
/*
* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled.
*/
writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
/*
* Set priority on PPI and SGI interrupts
*/
for (i = 0; i < 32; i += 4)
writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
writel(0xf0, base + GIC_CPU_PRIMASK);
writel(1, base + GIC_CPU_CTRL);
}
......
......@@ -75,7 +75,7 @@ extern unsigned long it8152_base_address;
IT8152_PD_IRQ(1) USB (USBR)
IT8152_PD_IRQ(0) Audio controller (ACR)
*/
#define IT8152_IRQ(x) (IRQ_BOARD_END + (x))
#define IT8152_IRQ(x) (IRQ_BOARD_START + (x))
/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
#define IT8152_LD_IRQ_COUNT 9
......
......@@ -748,8 +748,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
breakpoint_handler(addr, regs);
break;
case ARM_ENTRY_ASYNC_WATCHPOINT:
WARN_ON("Asynchronous watchpoint exception taken. "
"Debugging results may be unreliable");
WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");
case ARM_ENTRY_SYNC_WATCHPOINT:
watchpoint_handler(addr, regs);
break;
......
......@@ -1749,7 +1749,7 @@ static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
enum armv7_counters counter)
{
int ret;
int ret = 0;
if (counter == ARMV7_CYCLE_COUNTER)
ret = pmnc & ARMV7_FLAG_C;
......
......@@ -28,7 +28,7 @@ int notrace unwind_frame(struct stackframe *frame)
/* only go to a higher address on the stack */
low = frame->sp;
high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE;
high = ALIGN(low, THREAD_SIZE);
/* check current frame pointer is within bounds */
if (fp < (low + 12) || fp + 4 >= high)
......
......@@ -53,10 +53,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
{
#ifdef CONFIG_KALLSYMS
char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
sprint_symbol(sym1, where);
sprint_symbol(sym2, from);
printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
#else
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif
......
......@@ -279,7 +279,7 @@ int unwind_frame(struct stackframe *frame)
/* only go to a higher address on the stack */
low = frame->sp;
high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE;
high = ALIGN(low, THREAD_SIZE);
pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
frame->pc, frame->lr, frame->sp);
......
/*
* arch/arm/mach-ep93xx/include/mach/dma.h
/**
* DOC: EP93xx DMA M2P memory to peripheral and peripheral to memory engine
*
* The EP93xx DMA M2P subsystem handles DMA transfers between memory and
* peripherals. DMA M2P channels are available for audio, UARTs and IrDA.
* See chapter 10 of the EP93xx users guide for full details on the DMA M2P
* engine.
*
* See sound/soc/ep93xx/ep93xx-pcm.c for an example use of the DMA M2P code.
*
*/
#ifndef __ASM_ARCH_DMA_H
......@@ -8,12 +16,34 @@
#include <linux/list.h>
#include <linux/types.h>
/**
* struct ep93xx_dma_buffer - Information about a buffer to be transferred
* using the DMA M2P engine
*
* @list: Entry in DMA buffer list
* @bus_addr: Physical address of the buffer
* @size: Size of the buffer in bytes
*/
struct ep93xx_dma_buffer {
struct list_head list;
u32 bus_addr;
u16 size;
};
/**
* struct ep93xx_dma_m2p_client - Information about a DMA M2P client
*
* @name: Unique name for this client
* @flags: Client flags
* @cookie: User data to pass to callback functions
* @buffer_started: Non NULL function to call when a transfer is started.
* The arguments are the user data cookie and the DMA
* buffer which is starting.
* @buffer_finished: Non NULL function to call when a transfer is completed.
* The arguments are the user data cookie, the DMA buffer
* which has completed, and a boolean flag indicating if
* the transfer had an error.
*/
struct ep93xx_dma_m2p_client {
char *name;
u8 flags;
......@@ -24,10 +54,11 @@ struct ep93xx_dma_m2p_client {
struct ep93xx_dma_buffer *buf,
int bytes, int error);
/* Internal to the DMA code. */
/* private: Internal use only */
void *channel;
};
/* DMA M2P ports */
#define EP93XX_DMA_M2P_PORT_I2S1 0x00
#define EP93XX_DMA_M2P_PORT_I2S2 0x01
#define EP93XX_DMA_M2P_PORT_AAC1 0x02
......@@ -39,18 +70,80 @@ struct ep93xx_dma_m2p_client {
#define EP93XX_DMA_M2P_PORT_UART3 0x08
#define EP93XX_DMA_M2P_PORT_IRDA 0x09
#define EP93XX_DMA_M2P_PORT_MASK 0x0f
#define EP93XX_DMA_M2P_TX 0x00
#define EP93XX_DMA_M2P_RX 0x10
#define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20
#define EP93XX_DMA_M2P_IGNORE_ERROR 0x40
#define EP93XX_DMA_M2P_ERROR_MASK 0x60
int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p);
/* DMA M2P client flags */
#define EP93XX_DMA_M2P_TX 0x00 /* Memory to peripheral */
#define EP93XX_DMA_M2P_RX 0x10 /* Peripheral to memory */
/*
* DMA M2P client error handling flags. See the EP93xx users guide
* documentation on the DMA M2P CONTROL register for more details
*/
#define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20 /* Abort on peripheral error */
#define EP93XX_DMA_M2P_IGNORE_ERROR 0x40 /* Ignore peripheral errors */
#define EP93XX_DMA_M2P_ERROR_MASK 0x60 /* Mask of error bits */
/**
* ep93xx_dma_m2p_client_register - Register a client with the DMA M2P
* subsystem
*
* @m2p: Client information to register
* returns 0 on success
*
* The DMA M2P subsystem allocates a channel and an interrupt line for the DMA
* client
*/
int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p);
/**
* ep93xx_dma_m2p_client_unregister - Unregister a client from the DMA M2P
* subsystem
*
* @m2p: Client to unregister
*
* Any transfers currently in progress will be completed in hardware, but
* ignored in software.
*/
void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p);
/**
* ep93xx_dma_m2p_submit - Submit a DMA M2P transfer
*
* @m2p: DMA Client to submit the transfer on
* @buf: DMA Buffer to submit
*
* If the current or next transfer positions are free on the M2P client then
* the transfer is started immediately. If not, the transfer is added to the
* list of pending transfers. This function must not be called from the
* buffer_finished callback for an M2P channel.
*
*/
void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p,
struct ep93xx_dma_buffer *buf);
/**
* ep93xx_dma_m2p_submit_recursive - Put a DMA transfer on the pending list
* for an M2P channel
*
* @m2p: DMA Client to submit the transfer on
* @buf: DMA Buffer to submit
*
* This function must only be called from the buffer_finished callback for an
* M2P channel. It is commonly used to add the next transfer in a chained list
* of DMA transfers.
*/
void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p,
struct ep93xx_dma_buffer *buf);
/**
* ep93xx_dma_m2p_flush - Flush all pending transfers on a DMA M2P client
*
* @m2p: DMA client to flush transfers on
*
* Any transfers currently in progress will be completed in hardware, but
* ignored in software.
*
*/
void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p);
#endif /* __ASM_ARCH_DMA_H */
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment