Commit 923f7974 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild

Pull kbuild changes from Michal Marek:
 - Unification of cmd_uimage among archs that use it
 - make headers_check tries harder before reporting a missing
   <linux/types.h> include
 - kbuild portability fix for shells that do not support echo -e
 - make clean descends into samples/
 - setlocalversion grep fix
 - modpost typo fix
 - dtc warnings fix

* 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild:
  setlocalversion: Use "grep -q" instead of piping output to "read dummy"
  modpost: fix ALL_INIT_DATA_SECTIONS
  Kbuild: centralize MKIMAGE and cmd_uimage definitions
  headers_check: recursively search for linux/types.h inclusion
  scripts/Kbuild.include: Fix portability problem of "echo -e"
  scripts: dtc: fix compile warnings
  kbuild: clean up samples directory
  kbuild: disable -Wmissing-field-initializers for W=1
parents a7697b94 7f3bd6c9
...@@ -1170,7 +1170,7 @@ MRPROPER_FILES += .config .config.old .version .old_version \ ...@@ -1170,7 +1170,7 @@ MRPROPER_FILES += .config .config.old .version .old_version \
# #
clean: rm-dirs := $(CLEAN_DIRS) clean: rm-dirs := $(CLEAN_DIRS)
clean: rm-files := $(CLEAN_FILES) clean: rm-files := $(CLEAN_FILES)
clean-dirs := $(addprefix _clean_, . $(vmlinux-alldirs) Documentation) clean-dirs := $(addprefix _clean_, . $(vmlinux-alldirs) Documentation samples)
PHONY += $(clean-dirs) clean archclean PHONY += $(clean-dirs) clean archclean
$(clean-dirs): $(clean-dirs):
......
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
# Copyright (C) 1995-2002 Russell King # Copyright (C) 1995-2002 Russell King
# #
MKIMAGE := $(srctree)/scripts/mkuboot.sh
ifneq ($(MACHINE),) ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot include $(srctree)/$(MACHINE)/Makefile.boot
endif endif
...@@ -69,22 +67,19 @@ $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y)) ...@@ -69,22 +67,19 @@ $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
clean-files := *.dtb clean-files := *.dtb
quiet_cmd_uimage = UIMAGE $@ ifneq ($(LOADADDR),)
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ UIMAGE_LOADADDR=$(LOADADDR)
-C none -a $(LOADADDR) -e $(STARTADDR) \
-n 'Linux-$(KERNELRELEASE)' -d $< $@
ifeq ($(CONFIG_ZBOOT_ROM),y)
$(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
else else
$(obj)/uImage: LOADADDR=$(ZRELADDR) ifeq ($(CONFIG_ZBOOT_ROM),y)
UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
else
UIMAGE_LOADADDR=$(ZRELADDR)
endif
endif endif
$(obj)/uImage: STARTADDR=$(LOADADDR)
check_for_multiple_loadaddr = \ check_for_multiple_loadaddr = \
if [ $(words $(LOADADDR)) -gt 1 ]; then \ if [ $(words $(UIMAGE_LOADADDR)) -gt 1 ]; then \
echo 'multiple load addresses: $(LOADADDR)'; \ echo 'multiple load addresses: $(UIMAGE_LOADADDR)'; \
echo 'This is incompatible with uImages'; \ echo 'This is incompatible with uImages'; \
echo 'Specify LOADADDR on the commandline to build an uImage'; \ echo 'Specify LOADADDR on the commandline to build an uImage'; \
false; \ false; \
......
...@@ -6,8 +6,6 @@ ...@@ -6,8 +6,6 @@
# for more details. # for more details.
# #
MKIMAGE := $(srctree)/scripts/mkuboot.sh
extra-y := vmlinux.bin vmlinux.gz extra-y := vmlinux.bin vmlinux.gz
OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note.gnu.build-id OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note.gnu.build-id
...@@ -17,10 +15,9 @@ $(obj)/vmlinux.bin: vmlinux FORCE ...@@ -17,10 +15,9 @@ $(obj)/vmlinux.bin: vmlinux FORCE
$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip) $(call if_changed,gzip)
quiet_cmd_uimage = UIMAGE $@ UIMAGE_LOADADDR = $(CONFIG_LOAD_ADDRESS)
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A avr32 -O linux -T kernel \ UIMAGE_ENTRYADDR = $(CONFIG_ENTRY_ADDRESS)
-C gzip -a $(CONFIG_LOAD_ADDRESS) -e $(CONFIG_ENTRY_ADDRESS) \ UIMAGE_COMPRESSION = gzip
-n 'Linux-$(KERNELRELEASE)' -d $< $@
targets += uImage uImage.srec targets += uImage uImage.srec
$(obj)/uImage: $(obj)/vmlinux.gz $(obj)/uImage: $(obj)/vmlinux.gz
......
...@@ -6,20 +6,17 @@ ...@@ -6,20 +6,17 @@
# for more details. # for more details.
# #
MKIMAGE := $(srctree)/scripts/mkuboot.sh
targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.lzo vmImage.xip targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.lzo vmImage.xip
extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.xip extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.xip
UIMAGE_OPTS-y := ifeq ($(CONFIG_RAMKERNEL),y)
UIMAGE_OPTS-$(CONFIG_RAMKERNEL) += -a $(CONFIG_BOOT_LOAD) UIMAGE_LOADADDR = $(CONFIG_BOOT_LOAD)
UIMAGE_OPTS-$(CONFIG_ROMKERNEL) += -a $(CONFIG_ROM_BASE) -x else # CONFIG_ROMKERNEL must be set
UIMAGE_LOADADDR = $(CONFIG_ROM_BASE)
quiet_cmd_uimage = UIMAGE $@ endif
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \ UIMAGE_ENTRYADDR = $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}')
-C $(2) -n '$(CPU_REV)-$(KERNELRELEASE)' \ UIMAGE_NAME = '$(CPU_REV)-$(KERNELRELEASE)'
-e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \ UIMAGE_OPTS-$(CONFIG_ROMKERNEL) += -x
$(UIMAGE_OPTS-y) -d $< $@
$(obj)/vmlinux.bin: vmlinux FORCE $(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
# arch/microblaze/boot/Makefile # arch/microblaze/boot/Makefile
# #
MKIMAGE := $(srctree)/scripts/mkuboot.sh
obj-y += linked_dtb.o obj-y += linked_dtb.o
targets := linux.bin linux.bin.gz simpleImage.% targets := linux.bin linux.bin.gz simpleImage.%
...@@ -35,11 +33,9 @@ quiet_cmd_strip = STRIP $@ ...@@ -35,11 +33,9 @@ quiet_cmd_strip = STRIP $@
cmd_strip = $(STRIP) -K microblaze_start -K _end -K __log_buf \ cmd_strip = $(STRIP) -K microblaze_start -K _end -K __log_buf \
-K _fdt_start vmlinux -o $@ -K _fdt_start vmlinux -o $@
quiet_cmd_uimage = UIMAGE $@.ub UIMAGE_IN = $@
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A microblaze -O linux -T kernel \ UIMAGE_OUT = $@.ub
-C none -n 'Linux-$(KERNELRELEASE)' \ UIMAGE_LOADADDR = $(CONFIG_KERNEL_BASE_ADDR)
-a $(CONFIG_KERNEL_BASE_ADDR) -e $(CONFIG_KERNEL_BASE_ADDR) \
-d $@ $@.ub
$(obj)/simpleImage.%: vmlinux FORCE $(obj)/simpleImage.%: vmlinux FORCE
$(call if_changed,cp,.unstrip) $(call if_changed,cp,.unstrip)
......
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
# Copyright (C) 1999 Stuart Menefy # Copyright (C) 1999 Stuart Menefy
# #
MKIMAGE := $(srctree)/scripts/mkuboot.sh
# #
# Assign safe dummy values if these variables are not defined, # Assign safe dummy values if these variables are not defined,
# in order to suppress error message. # in order to suppress error message.
...@@ -61,10 +59,8 @@ KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \ ...@@ -61,10 +59,8 @@ KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \
$(KERNEL_MEMORY) + \ $(KERNEL_MEMORY) + \
$(CONFIG_ZERO_PAGE_OFFSET) + $(CONFIG_ENTRY_OFFSET)]') $(CONFIG_ZERO_PAGE_OFFSET) + $(CONFIG_ENTRY_OFFSET)]')
quiet_cmd_uimage = UIMAGE $@ UIMAGE_LOADADDR = $(KERNEL_LOAD)
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \ UIMAGE_ENTRYADDR = $(KERNEL_ENTRY)
-C $(2) -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
-n 'Linux-$(KERNELRELEASE)' -d $< $@
$(obj)/vmlinux.bin: vmlinux FORCE $(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
ROOT_IMG := /usr/src/root.img ROOT_IMG := /usr/src/root.img
ELFTOAOUT := elftoaout ELFTOAOUT := elftoaout
MKIMAGE := $(srctree)/scripts/mkuboot.sh
hostprogs-y := piggyback btfixupprep hostprogs-y := piggyback btfixupprep
targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout
...@@ -92,11 +91,9 @@ $(obj)/image.bin: $(obj)/image FORCE ...@@ -92,11 +91,9 @@ $(obj)/image.bin: $(obj)/image FORCE
$(obj)/image.gz: $(obj)/image.bin $(obj)/image.gz: $(obj)/image.bin
$(call if_changed,gzip) $(call if_changed,gzip)
quiet_cmd_uimage = UIMAGE $@ UIMAGE_LOADADDR = $(CONFIG_UBOOT_LOAD_ADDR)
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sparc -O linux -T kernel \ UIMAGE_ENTRYADDR = $(CONFIG_UBOOT_ENTRY_ADDR)
-C gzip -a $(CONFIG_UBOOT_LOAD_ADDR) \ UIMAGE_COMPRESSION = gzip
-e $(CONFIG_UBOOT_ENTRY_ADDR) -n 'Linux-$(KERNELRELEASE)' \
-d $< $@
quiet_cmd_uimage.o = UIMAGE.O $@ quiet_cmd_uimage.o = UIMAGE.O $@
cmd_uimage.o = $(LD) -Tdata $(CONFIG_UBOOT_FLASH_ADDR) \ cmd_uimage.o = $(LD) -Tdata $(CONFIG_UBOOT_FLASH_ADDR) \
......
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
# Copyright (C) 2001~2010 GUAN Xue-tao # Copyright (C) 2001~2010 GUAN Xue-tao
# #
MKIMAGE := $(srctree)/scripts/mkuboot.sh
targets := Image zImage uImage targets := Image zImage uImage
$(obj)/Image: vmlinux FORCE $(obj)/Image: vmlinux FORCE
...@@ -26,14 +24,8 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE ...@@ -26,14 +24,8 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
@echo ' Kernel: $@ is ready' @echo ' Kernel: $@ is ready'
quiet_cmd_uimage = UIMAGE $@ UIMAGE_ARCH = unicore
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A unicore -O linux -T kernel \ UIMAGE_LOADADDR = 0x0
-C none -a $(LOADADDR) -e $(STARTADDR) \
-n 'Linux-$(KERNELRELEASE)' -d $< $@
$(obj)/uImage: LOADADDR=0x0
$(obj)/uImage: STARTADDR=$(LOADADDR)
$(obj)/uImage: $(obj)/zImage FORCE $(obj)/uImage: $(obj)/zImage FORCE
$(call if_changed,uimage) $(call if_changed,uimage)
......
...@@ -104,7 +104,7 @@ as-option = $(call try-run,\ ...@@ -104,7 +104,7 @@ as-option = $(call try-run,\
# Usage: cflags-y += $(call as-instr,instr,option1,option2) # Usage: cflags-y += $(call as-instr,instr,option1,option2)
as-instr = $(call try-run,\ as-instr = $(call try-run,\
/bin/echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3)) printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
# cc-option # cc-option
# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
......
...@@ -69,6 +69,7 @@ warning-1 += -Wmissing-prototypes ...@@ -69,6 +69,7 @@ warning-1 += -Wmissing-prototypes
warning-1 += -Wold-style-definition warning-1 += -Wold-style-definition
warning-1 += $(call cc-option, -Wmissing-include-dirs) warning-1 += $(call cc-option, -Wmissing-include-dirs)
warning-1 += $(call cc-option, -Wunused-but-set-variable) warning-1 += $(call cc-option, -Wunused-but-set-variable)
warning-1 += $(call cc-disable-warning, missing-field-initializers)
warning-2 := -Waggregate-return warning-2 := -Waggregate-return
warning-2 += -Wcast-align warning-2 += -Wcast-align
...@@ -76,6 +77,7 @@ warning-2 += -Wdisabled-optimization ...@@ -76,6 +77,7 @@ warning-2 += -Wdisabled-optimization
warning-2 += -Wnested-externs warning-2 += -Wnested-externs
warning-2 += -Wshadow warning-2 += -Wshadow
warning-2 += $(call cc-option, -Wlogical-op) warning-2 += $(call cc-option, -Wlogical-op)
warning-2 += $(call cc-option, -Wmissing-field-initializers)
warning-3 := -Wbad-function-cast warning-3 := -Wbad-function-cast
warning-3 += -Wcast-qual warning-3 += -Wcast-qual
......
...@@ -304,6 +304,30 @@ cmd_lzo = (cat $(filter-out FORCE,$^) | \ ...@@ -304,6 +304,30 @@ cmd_lzo = (cat $(filter-out FORCE,$^) | \
lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
(rm -f $@ ; false) (rm -f $@ ; false)
# U-Boot mkimage
# ---------------------------------------------------------------------------
MKIMAGE := $(srctree)/scripts/mkuboot.sh
# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces
# the number of overrides in arch makefiles
UIMAGE_ARCH ?= $(SRCARCH)
UIMAGE_COMPRESSION ?= $(if $(2),$(2),none)
UIMAGE_OPTS-y ?=
UIMAGE_TYPE ?= kernel
UIMAGE_LOADADDR ?= arch_must_set_this
UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)
UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)'
UIMAGE_IN ?= $<
UIMAGE_OUT ?= $@
quiet_cmd_uimage = UIMAGE $(UIMAGE_OUT)
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \
-C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \
-T $(UIMAGE_TYPE) \
-a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
-n $(UIMAGE_NAME) -d $(UIMAGE_IN) $(UIMAGE_OUT)
# XZ # XZ
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Use xzkern to compress the kernel image and xzmisc to compress other things. # Use xzkern to compress the kernel image and xzmisc to compress other things.
......
...@@ -101,7 +101,7 @@ int main(int argc, char *argv[]) ...@@ -101,7 +101,7 @@ int main(int argc, char *argv[])
const char *outform = "dts"; const char *outform = "dts";
const char *outname = "-"; const char *outname = "-";
const char *depname = NULL; const char *depname = NULL;
int force = 0, check = 0, sort = 0; int force = 0, sort = 0;
const char *arg; const char *arg;
int opt; int opt;
FILE *outf = NULL; FILE *outf = NULL;
...@@ -143,9 +143,6 @@ int main(int argc, char *argv[]) ...@@ -143,9 +143,6 @@ int main(int argc, char *argv[])
case 'f': case 'f':
force = 1; force = 1;
break; break;
case 'c':
check = 1;
break;
case 'q': case 'q':
quiet++; quiet++;
break; break;
......
...@@ -697,7 +697,6 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) ...@@ -697,7 +697,6 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
{ {
struct reserve_info *reservelist = NULL; struct reserve_info *reservelist = NULL;
struct reserve_info *new; struct reserve_info *new;
const char *p;
struct fdt_reserve_entry re; struct fdt_reserve_entry re;
/* /*
...@@ -706,7 +705,6 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) ...@@ -706,7 +705,6 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
* *
* First pass, count entries. * First pass, count entries.
*/ */
p = inb->ptr;
while (1) { while (1) {
flat_read_chunk(inb, &re, sizeof(re)); flat_read_chunk(inb, &re, sizeof(re));
re.address = fdt64_to_cpu(re.address); re.address = fdt64_to_cpu(re.address);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
# 3) Check for leaked CONFIG_ symbols # 3) Check for leaked CONFIG_ symbols
use strict; use strict;
use File::Basename;
my ($dir, $arch, @files) = @ARGV; my ($dir, $arch, @files) = @ARGV;
...@@ -99,6 +100,39 @@ sub check_asm_types ...@@ -99,6 +100,39 @@ sub check_asm_types
} }
my $linux_types; my $linux_types;
my %import_stack = ();
sub check_include_typesh
{
my $path = $_[0];
my $import_path;
my $fh;
my @file_paths = ($path, $dir . "/" . $path, dirname($filename) . "/" . $path);
for my $possible ( @file_paths ) {
if (not $import_stack{$possible} and open($fh, '<', $possible)) {
$import_path = $possible;
$import_stack{$import_path} = 1;
last;
}
}
if (eof $fh) {
return;
}
my $line;
while ($line = <$fh>) {
if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
$linux_types = 1;
last;
}
if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) {
check_include_typesh($included);
}
}
close $fh;
delete $import_stack{$import_path};
}
sub check_sizetypes sub check_sizetypes
{ {
if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
...@@ -113,6 +147,9 @@ sub check_sizetypes ...@@ -113,6 +147,9 @@ sub check_sizetypes
$linux_types = 1; $linux_types = 1;
return; return;
} }
if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) {
check_include_typesh($included);
}
if ($line =~ m/__[us](8|16|32|64)\b/) { if ($line =~ m/__[us](8|16|32|64)\b/) {
printf STDERR "$filename:$lineno: " . printf STDERR "$filename:$lineno: " .
"found __[us]{8,16,32,64} type " . "found __[us]{8,16,32,64} type " .
...@@ -122,4 +159,3 @@ sub check_sizetypes ...@@ -122,4 +159,3 @@ sub check_sizetypes
#$ret = 1; #$ret = 1;
} }
} }
...@@ -849,7 +849,7 @@ static void check_section(const char *modname, struct elf_info *elf, ...@@ -849,7 +849,7 @@ static void check_section(const char *modname, struct elf_info *elf,
#define ALL_INIT_DATA_SECTIONS \ #define ALL_INIT_DATA_SECTIONS \
".init.setup$", ".init.rodata$", \ ".init.setup$", ".init.rodata$", \
".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$" \ ".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$", \
".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$" ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$"
#define ALL_EXIT_DATA_SECTIONS \ #define ALL_EXIT_DATA_SECTIONS \
".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$" ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$"
......
...@@ -75,8 +75,7 @@ scm_version() ...@@ -75,8 +75,7 @@ scm_version()
[ -w . ] && git update-index --refresh --unmerged > /dev/null [ -w . ] && git update-index --refresh --unmerged > /dev/null
# Check for uncommitted changes # Check for uncommitted changes
if git diff-index --name-only HEAD | grep -v "^scripts/package" \ if git diff-index --name-only HEAD | grep -qv "^scripts/package"; then
| read dummy; then
printf '%s' -dirty printf '%s' -dirty
fi fi
......
Markdown is supported
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