Commit 7eebd09b authored by Anton Altaparmakov's avatar Anton Altaparmakov

Merge cantab.net:/usr/src/bklinux-2.6 into cantab.net:/usr/src/ntfs-2.6

parents 3c23072e 7ce42ae1
...@@ -483,6 +483,14 @@ ia32_syscall_table: ...@@ -483,6 +483,14 @@ ia32_syscall_table:
data8 sys32_fadvise64_64 data8 sys32_fadvise64_64
data8 sys_ni_syscall data8 sys_ni_syscall
data8 sys_ni_syscall data8 sys_ni_syscall
data8 sys_ni_syscall /* 275 */
data8 sys_ni_syscall
data8 compat_sys_mq_open
data8 sys_mq_unlink
data8 compat_sys_mq_timedsend
data8 compat_sys_mq_timedreceive /* 280 */
data8 compat_sys_mq_notify
data8 compat_sys_mq_getsetattr
// guard against failures to increase IA32_NR_syscalls // guard against failures to increase IA32_NR_syscalls
.org ia32_syscall_table + 8*IA32_NR_syscalls .org ia32_syscall_table + 8*IA32_NR_syscalls
...@@ -169,7 +169,12 @@ copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from) ...@@ -169,7 +169,12 @@ copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from)
addr = (unsigned long) from->si_ptr; addr = (unsigned long) from->si_ptr;
err |= __put_user(addr, &to->si_ptr); err |= __put_user(addr, &to->si_ptr);
break; break;
/* case __SI_RT: This is not generated by the kernel as of now. */ case __SI_RT >> 16: /* Not generated by the kernel as of now. */
case __SI_MESGQ >> 16:
err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user(from->si_pid, &to->si_pid);
err |= __put_user(from->si_ptr, &to->si_ptr);
break;
} }
} }
return err; return err;
...@@ -612,7 +617,6 @@ sys32_rt_sigtimedwait (compat_sigset_t *uthese, siginfo_t32 *uinfo, ...@@ -612,7 +617,6 @@ sys32_rt_sigtimedwait (compat_sigset_t *uthese, siginfo_t32 *uinfo,
asmlinkage long asmlinkage long
sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 *uinfo) sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 *uinfo)
{ {
extern int copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from);
mm_segment_t old_fs = get_fs(); mm_segment_t old_fs = get_fs();
siginfo_t info; siginfo_t info;
int ret; int ret;
......
...@@ -1504,12 +1504,12 @@ sys_call_table: ...@@ -1504,12 +1504,12 @@ sys_call_table:
data8 sys_ni_syscall data8 sys_ni_syscall
data8 sys_ni_syscall // 1260 data8 sys_ni_syscall // 1260
data8 sys_ni_syscall data8 sys_ni_syscall
data8 sys_ni_syscall data8 sys_mq_open
data8 sys_ni_syscall data8 sys_mq_unlink
data8 sys_ni_syscall data8 sys_mq_timedsend
data8 sys_ni_syscall // 1265 data8 sys_mq_timedreceive // 1265
data8 sys_ni_syscall data8 sys_mq_notify
data8 sys_ni_syscall data8 sys_mq_getsetattr
data8 sys_ni_syscall data8 sys_ni_syscall
data8 sys_ni_syscall data8 sys_ni_syscall
data8 sys_ni_syscall // 1270 data8 sys_ni_syscall // 1270
......
...@@ -851,12 +851,12 @@ fsyscall_table: ...@@ -851,12 +851,12 @@ fsyscall_table:
data8 0 data8 0
data8 0 // 1260 data8 0 // 1260
data8 0 data8 0
data8 0 data8 0 // mq_open
data8 0 data8 0 // mq_unlink
data8 0 data8 0 // mq_timedsend
data8 0 // 1265 data8 0 // mq_timedreceive // 1265
data8 0 data8 0 // mq_notify
data8 0 data8 0 // mq_getsetattr
data8 0 data8 0
data8 0 data8 0
data8 0 // 1270 data8 0 // 1270
......
...@@ -293,7 +293,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) ...@@ -293,7 +293,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
irq &= (~IA64_IRQ_REDIRECTED); irq &= (~IA64_IRQ_REDIRECTED);
vec = irq_to_vector(irq); vec = irq_to_vector(irq);
if (cpus_empty(mask) || vec >= IA64_NUM_VECTORS) if (cpus_empty(mask))
return; return;
dest = cpu_physical_id(first_cpu(mask)); dest = cpu_physical_id(first_cpu(mask));
......
...@@ -205,6 +205,12 @@ copy_siginfo_to_user (siginfo_t *to, siginfo_t *from) ...@@ -205,6 +205,12 @@ copy_siginfo_to_user (siginfo_t *to, siginfo_t *from)
err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_overrun, &to->si_overrun);
err |= __put_user(from->si_ptr, &to->si_ptr); err |= __put_user(from->si_ptr, &to->si_ptr);
break; break;
case __SI_RT >> 16: /* Not generated by the kernel as of now. */
case __SI_MESGQ >> 16:
err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user(from->si_pid, &to->si_pid);
err |= __put_user(from->si_ptr, &to->si_ptr);
break;
case __SI_CHLD >> 16: case __SI_CHLD >> 16:
err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_utime, &to->si_utime);
err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_stime, &to->si_stime);
...@@ -213,45 +219,11 @@ copy_siginfo_to_user (siginfo_t *to, siginfo_t *from) ...@@ -213,45 +219,11 @@ copy_siginfo_to_user (siginfo_t *to, siginfo_t *from)
err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_pid, &to->si_pid);
break; break;
/* case __SI_RT: This is not generated by the kernel as of now. */
} }
return err; return err;
} }
} }
int
copy_siginfo_from_user (siginfo_t *to, siginfo_t *from)
{
if (!access_ok(VERIFY_READ, from, sizeof(siginfo_t)))
return -EFAULT;
if (__copy_from_user(to, from, sizeof(siginfo_t)) != 0)
return -EFAULT;
if (SI_FROMUSER(to))
return 0;
to->si_code &= ~__SI_MASK;
if (to->si_code != 0) {
switch (to->si_signo) {
case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGTRAP:
to->si_code |= __SI_FAULT;
break;
case SIGCHLD:
to->si_code |= __SI_CHLD;
break;
case SIGPOLL:
to->si_code |= __SI_POLL;
break;
default:
break;
}
}
return 0;
}
long long
ia64_rt_sigreturn (struct sigscratch *scr) ia64_rt_sigreturn (struct sigscratch *scr)
{ {
...@@ -445,6 +417,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, ...@@ -445,6 +417,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */ scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */
scr->pt.cr_iip = tramp_addr; scr->pt.cr_iip = tramp_addr;
ia64_psr(&scr->pt)->ri = 0; /* start executing in first slot */ ia64_psr(&scr->pt)->ri = 0; /* start executing in first slot */
ia64_psr(&scr->pt)->be = 0; /* force little-endian byte-order */
/* /*
* Force the interruption function mask to zero. This has no effect when a * Force the interruption function mask to zero. This has no effect when a
* system-call got interrupted by a signal (since, in that case, scr->pt_cr_ifs is * system-call got interrupted by a signal (since, in that case, scr->pt_cr_ifs is
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */ #include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/module.h> /* for EXPORT_SYMBOL */
#include <asm/fpswa.h> #include <asm/fpswa.h>
#include <asm/hardirq.h> #include <asm/hardirq.h>
...@@ -47,6 +48,7 @@ register double f30 asm ("f30"); register double f31 asm ("f31"); ...@@ -47,6 +48,7 @@ register double f30 asm ("f30"); register double f31 asm ("f31");
extern spinlock_t timerlist_lock; extern spinlock_t timerlist_lock;
fpswa_interface_t *fpswa_interface; fpswa_interface_t *fpswa_interface;
EXPORT_SYMBOL(fpswa_interface);
void __init void __init
trap_init (void) trap_init (void)
......
...@@ -54,56 +54,33 @@ struct pci_fixup pcibios_fixups[1]; ...@@ -54,56 +54,33 @@ struct pci_fixup pcibios_fixups[1];
* synchronization mechanism here. * synchronization mechanism here.
*/ */
#define PCI_SAL_ADDRESS(seg, bus, devfn, reg) \ #define PCI_SAL_ADDRESS(seg, bus, devfn, reg) \
((u64)(seg << 24) | (u64)(bus << 16) | \ ((u64)(seg << 24) | (u64)(bus << 16) | \
(u64)(devfn << 8) | (u64)(reg)) (u64)(devfn << 8) | (u64)(reg))
static int
pci_sal_read (int seg, int bus, int devfn, int reg, int len, u32 *value)
{
int result = 0;
u64 data = 0;
if ((seg > 255) || (bus > 255) || (devfn > 255) || (reg > 255))
return -EINVAL;
result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, devfn, reg), 0, len, &data);
*value = (u32) data;
return result;
}
static int
pci_sal_write (int seg, int bus, int devfn, int reg, int len, u32 value)
{
if ((seg > 255) || (bus > 255) || (devfn > 255) || (reg > 255))
return -EINVAL;
return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, devfn, reg), 0, len, value);
}
static struct pci_raw_ops pci_sal_ops = {
.read = pci_sal_read,
.write = pci_sal_write
};
/* SAL 3.2 adds support for extended config space. */ /* SAL 3.2 adds support for extended config space. */
#define PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg) \ #define PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg) \
((u64)(seg << 28) | (u64)(bus << 20) | \ ((u64)(seg << 28) | (u64)(bus << 20) | \
(u64)(devfn << 12) | (u64)(reg)) (u64)(devfn << 12) | (u64)(reg))
static int static int
pci_sal_ext_read (int seg, int bus, int devfn, int reg, int len, u32 *value) pci_sal_read (int seg, int bus, int devfn, int reg, int len, u32 *value)
{ {
u64 addr, mode, data = 0;
int result = 0; int result = 0;
u64 data = 0;
if ((seg > 65535) || (bus > 255) || (devfn > 255) || (reg > 4095)) if ((seg > 255) || (bus > 255) || (devfn > 255) || (reg > 4095))
return -EINVAL; return -EINVAL;
result = ia64_sal_pci_config_read(PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg), 1, len, &data); if ((seg | reg) <= 255) {
addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg);
mode = 0;
} else {
addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg);
mode = 1;
}
result = ia64_sal_pci_config_read(addr, mode, len, &data);
*value = (u32) data; *value = (u32) data;
...@@ -111,46 +88,42 @@ pci_sal_ext_read (int seg, int bus, int devfn, int reg, int len, u32 *value) ...@@ -111,46 +88,42 @@ pci_sal_ext_read (int seg, int bus, int devfn, int reg, int len, u32 *value)
} }
static int static int
pci_sal_ext_write (int seg, int bus, int devfn, int reg, int len, u32 value) pci_sal_write (int seg, int bus, int devfn, int reg, int len, u32 value)
{ {
u64 addr, mode;
if ((seg > 65535) || (bus > 255) || (devfn > 255) || (reg > 4095)) if ((seg > 65535) || (bus > 255) || (devfn > 255) || (reg > 4095))
return -EINVAL; return -EINVAL;
return ia64_sal_pci_config_write(PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg), 1, len, value); if ((seg | reg) <= 255) {
} addr = PCI_SAL_ADDRESS(seg, bus, devfn, reg);
mode = 0;
static struct pci_raw_ops pci_sal_ext_ops = { } else {
.read = pci_sal_ext_read, addr = PCI_SAL_EXT_ADDRESS(seg, bus, devfn, reg);
.write = pci_sal_ext_write mode = 1;
};
struct pci_raw_ops *raw_pci_ops = &pci_sal_ops; /* default to SAL < 3.2 */
static int __init
pci_set_sal_ops (void)
{
if (sal_revision >= SAL_VERSION_CODE(3, 2)) {
printk("Using SAL 3.2 to access PCI config space\n");
raw_pci_ops = &pci_sal_ext_ops;
} }
return 0; return ia64_sal_pci_config_write(addr, mode, len, value);
} }
arch_initcall(pci_set_sal_ops); static struct pci_raw_ops pci_sal_ops = {
.read = pci_sal_read,
.write = pci_sal_write
};
struct pci_raw_ops *raw_pci_ops = &pci_sal_ops;
static int static int
pci_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) pci_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
{ {
return raw_pci_ops->read(pci_domain_nr(bus), bus->number, return raw_pci_ops->read(pci_domain_nr(bus), bus->number,
devfn, where, size, value); devfn, where, size, value);
} }
static int static int
pci_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) pci_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
{ {
return raw_pci_ops->write(pci_domain_nr(bus), bus->number, return raw_pci_ops->write(pci_domain_nr(bus), bus->number,
devfn, where, size, value); devfn, where, size, value);
} }
static struct pci_ops pci_root_ops = { static struct pci_ops pci_root_ops = {
......
...@@ -1826,7 +1826,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page, ...@@ -1826,7 +1826,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
if (wbc->sync_mode != WB_SYNC_NONE || !wbc->nonblocking) { if (wbc->sync_mode != WB_SYNC_NONE || !wbc->nonblocking) {
lock_buffer(bh); lock_buffer(bh);
} else if (test_set_buffer_locked(bh)) { } else if (test_set_buffer_locked(bh)) {
__set_page_dirty_nobuffers(page); redirty_page_for_writepage(wbc, page);
continue; continue;
} }
if (test_clear_buffer_dirty(bh)) { if (test_clear_buffer_dirty(bh)) {
......
...@@ -1393,7 +1393,7 @@ static int ext3_ordered_writepage(struct page *page, ...@@ -1393,7 +1393,7 @@ static int ext3_ordered_writepage(struct page *page,
return ret; return ret;
out_fail: out_fail:
__set_page_dirty_nobuffers(page); redirty_page_for_writepage(wbc, page);
unlock_page(page); unlock_page(page);
return ret; return ret;
} }
...@@ -1422,7 +1422,7 @@ static int ext3_writeback_writepage(struct page *page, ...@@ -1422,7 +1422,7 @@ static int ext3_writeback_writepage(struct page *page,
return ret; return ret;
out_fail: out_fail:
__set_page_dirty_nobuffers(page); redirty_page_for_writepage(wbc, page);
unlock_page(page); unlock_page(page);
return ret; return ret;
} }
...@@ -1478,7 +1478,7 @@ static int ext3_journalled_writepage(struct page *page, ...@@ -1478,7 +1478,7 @@ static int ext3_journalled_writepage(struct page *page,
return ret; return ret;
no_write: no_write:
__set_page_dirty_nobuffers(page); redirty_page_for_writepage(wbc, page);
out_unlock: out_unlock:
unlock_page(page); unlock_page(page);
goto out; goto out;
......
...@@ -458,7 +458,7 @@ int ntfs_readpage(struct file *file, struct page *page) ...@@ -458,7 +458,7 @@ int ntfs_readpage(struct file *file, struct page *page)
* *
* Based on ntfs_read_block() and __block_write_full_page(). * Based on ntfs_read_block() and __block_write_full_page().
*/ */
static int ntfs_write_block(struct page *page) static int ntfs_write_block(struct writeback_control *wbc, struct page *page)
{ {
VCN vcn; VCN vcn;
LCN lcn; LCN lcn;
...@@ -499,10 +499,7 @@ static int ntfs_write_block(struct page *page) ...@@ -499,10 +499,7 @@ static int ntfs_write_block(struct page *page)
* Put the page back on mapping->dirty_pages, but leave its * Put the page back on mapping->dirty_pages, but leave its
* buffer's dirty state as-is. * buffer's dirty state as-is.
*/ */
// FIXME: Once Andrew's -EAGAIN patch goes in, remove the redirty_page_for_writepage(wbc, page);
// __set_page_dirty_nobuffers(page) and return -EAGAIN instead
// of zero.
__set_page_dirty_nobuffers(page);
unlock_page(page); unlock_page(page);
return 0; return 0;
} }
...@@ -733,10 +730,7 @@ static int ntfs_write_block(struct page *page) ...@@ -733,10 +730,7 @@ static int ntfs_write_block(struct page *page)
* Put the page back on mapping->dirty_pages, but * Put the page back on mapping->dirty_pages, but
* leave its buffer's dirty state as-is. * leave its buffer's dirty state as-is.
*/ */
// FIXME: Once Andrew's -EAGAIN patch goes in, remove redirty_page_for_writepage(wbc, page);
// the __set_page_dirty_nobuffers(page) and set err to
// -EAGAIN instead of zero.
__set_page_dirty_nobuffers(page);
err = 0; err = 0;
} else } else
SetPageError(page); SetPageError(page);
...@@ -869,7 +863,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) ...@@ -869,7 +863,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
} }
/* Normal data stream. */ /* Normal data stream. */
return ntfs_write_block(page); return ntfs_write_block(wbc, page);
} }
/* /*
...@@ -986,10 +980,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc) ...@@ -986,10 +980,7 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
* Put the page back on mapping->dirty_pages, but leave its * Put the page back on mapping->dirty_pages, but leave its
* buffer's dirty state as-is. * buffer's dirty state as-is.
*/ */
// FIXME: Once Andrew's -EAGAIN patch goes in, remove the redirty_page_for_writepage(wbc, page);
// __set_page_dirty_nobuffers(page) and set err to -EAGAIN
// instead of zero.
__set_page_dirty_nobuffers(page);
err = 0; err = 0;
} else { } else {
ntfs_error(vi->i_sb, "Resident attribute write failed with " ntfs_error(vi->i_sb, "Resident attribute write failed with "
......
...@@ -2112,7 +2112,7 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control ...@@ -2112,7 +2112,7 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
lock_buffer(bh); lock_buffer(bh);
} else { } else {
if (test_set_buffer_locked(bh)) { if (test_set_buffer_locked(bh)) {
__set_page_dirty_nobuffers(page); redirty_page_for_writepage(wbc, page);
continue; continue;
} }
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/signal.h> #include <asm/signal.h>
#define IA32_NR_syscalls 275 /* length of syscall table */ #define IA32_NR_syscalls 283 /* length of syscall table */
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
...@@ -136,8 +136,6 @@ copy_siginfo (siginfo_t *to, siginfo_t *from) ...@@ -136,8 +136,6 @@ copy_siginfo (siginfo_t *to, siginfo_t *from)
memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld)); memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
} }
extern int copy_siginfo_from_user(siginfo_t *to, siginfo_t *from);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_IA64_SIGINFO_H */ #endif /* _ASM_IA64_SIGINFO_H */
...@@ -251,6 +251,12 @@ ...@@ -251,6 +251,12 @@
#define __NR_reserved1 1259 /* reserved for NUMA interface */ #define __NR_reserved1 1259 /* reserved for NUMA interface */
#define __NR_reserved2 1260 /* reserved for NUMA interface */ #define __NR_reserved2 1260 /* reserved for NUMA interface */
#define __NR_reserved3 1261 /* reserved for NUMA interface */ #define __NR_reserved3 1261 /* reserved for NUMA interface */
#define __NR_mq_open 1262
#define __NR_mq_unlink 1263
#define __NR_mq_timedsend 1264
#define __NR_mq_timedreceive 1265
#define __NR_mq_notify 1266
#define __NR_mq_getsetattr 1267
#ifdef __KERNEL__ #ifdef __KERNEL__
......
...@@ -486,6 +486,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long ...@@ -486,6 +486,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long
int __set_page_dirty_buffers(struct page *page); int __set_page_dirty_buffers(struct page *page);
int __set_page_dirty_nobuffers(struct page *page); int __set_page_dirty_nobuffers(struct page *page);
int redirty_page_for_writepage(struct writeback_control *wbc,
struct page *page);
int FASTCALL(set_page_dirty(struct page *page)); int FASTCALL(set_page_dirty(struct page *page));
int set_page_dirty_lock(struct page *page); int set_page_dirty_lock(struct page *page);
int clear_page_dirty_for_io(struct page *page); int clear_page_dirty_for_io(struct page *page);
......
...@@ -579,6 +579,18 @@ int __set_page_dirty_nobuffers(struct page *page) ...@@ -579,6 +579,18 @@ int __set_page_dirty_nobuffers(struct page *page)
} }
EXPORT_SYMBOL(__set_page_dirty_nobuffers); EXPORT_SYMBOL(__set_page_dirty_nobuffers);
/*
* When a writepage implementation decides that it doesn't want to write this
* page for some reason, it should redirty the locked page via
* redirty_page_for_writepage() and it should then unlock the page and return 0
*/
int redirty_page_for_writepage(struct writeback_control *wbc, struct page *page)
{
wbc->pages_skipped++;
return __set_page_dirty_nobuffers(page);
}
EXPORT_SYMBOL(redirty_page_for_writepage);
/* /*
* If the mapping doesn't provide a set_page_dirty a_op, then * If the mapping doesn't provide a set_page_dirty a_op, then
* just fall through and assume that it wants buffer_heads. * just fall through and assume that it wants buffer_heads.
......
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