Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
e19f970b
Commit
e19f970b
authored
Apr 05, 2002
by
Bjorn Helgaas
Committed by
David Mosberger
Apr 05, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] Add support for HP zx1 systems.
parent
5dbc562f
Changes
26
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
2489 additions
and
15 deletions
+2489
-15
arch/ia64/Makefile
arch/ia64/Makefile
+12
-8
arch/ia64/config.in
arch/ia64/config.in
+2
-1
arch/ia64/dig/setup.c
arch/ia64/dig/setup.c
+0
-2
arch/ia64/hp/common/Makefile
arch/ia64/hp/common/Makefile
+14
-0
arch/ia64/hp/common/sba_iommu.c
arch/ia64/hp/common/sba_iommu.c
+1850
-0
arch/ia64/hp/sim/Makefile
arch/ia64/hp/sim/Makefile
+13
-0
arch/ia64/hp/sim/hpsim_console.c
arch/ia64/hp/sim/hpsim_console.c
+0
-0
arch/ia64/hp/sim/hpsim_irq.c
arch/ia64/hp/sim/hpsim_irq.c
+0
-0
arch/ia64/hp/sim/hpsim_machvec.c
arch/ia64/hp/sim/hpsim_machvec.c
+0
-0
arch/ia64/hp/sim/hpsim_setup.c
arch/ia64/hp/sim/hpsim_setup.c
+0
-0
arch/ia64/hp/sim/hpsim_ssc.h
arch/ia64/hp/sim/hpsim_ssc.h
+0
-0
arch/ia64/hp/zx1/Makefile
arch/ia64/hp/zx1/Makefile
+13
-0
arch/ia64/hp/zx1/hpzx1_machvec.c
arch/ia64/hp/zx1/hpzx1_machvec.c
+2
-0
arch/ia64/hp/zx1/hpzx1_misc.c
arch/ia64/hp/zx1/hpzx1_misc.c
+400
-0
arch/ia64/kernel/Makefile
arch/ia64/kernel/Makefile
+1
-0
arch/ia64/kernel/acpi.c
arch/ia64/kernel/acpi.c
+101
-3
arch/ia64/kernel/ia64_ksyms.c
arch/ia64/kernel/ia64_ksyms.c
+7
-0
arch/ia64/kernel/irq.c
arch/ia64/kernel/irq.c
+17
-0
arch/ia64/kernel/setup.c
arch/ia64/kernel/setup.c
+2
-0
arch/ia64/mm/tlb.c
arch/ia64/mm/tlb.c
+1
-1
drivers/pci/pci.ids
drivers/pci/pci.ids
+3
-0
include/asm-ia64/hw_irq.h
include/asm-ia64/hw_irq.h
+2
-0
include/asm-ia64/machvec.h
include/asm-ia64/machvec.h
+4
-0
include/asm-ia64/machvec_hpzx1.h
include/asm-ia64/machvec_hpzx1.h
+37
-0
include/asm-ia64/machvec_init.h
include/asm-ia64/machvec_init.h
+5
-0
include/linux/pci_ids.h
include/linux/pci_ids.h
+3
-0
No files found.
arch/ia64/Makefile
View file @
e19f970b
...
...
@@ -33,16 +33,11 @@ ifeq ($(CONFIG_ITANIUM_BSTEP_SPECIFIC),y)
endif
ifdef
CONFIG_IA64_GENERIC
CORE_FILES
:=
arch
/
$(ARCH)
/hp/hp.a
\
arch
/
$(ARCH)
/sn/sn.o
\
arch
/
$(ARCH)
/dig/dig.a
\
arch
/
$(ARCH)
/sn/io/sgiio.o
\
CORE_FILES
:=
arch
/
$(ARCH)
/hp/hp.o
\
arch
/
$(ARCH)
/dig/dig.a
\
$(CORE_FILES)
SUBDIRS
:=
arch
/
$(ARCH)
/hp
\
arch
/
$(ARCH)
/sn/sn1
\
arch
/
$(ARCH)
/sn
\
arch
/
$(ARCH)
/dig
\
arch
/
$(ARCH)
/sn/io
\
$(SUBDIRS)
else
# !GENERIC
...
...
@@ -50,7 +45,16 @@ else # !GENERIC
ifdef
CONFIG_IA64_HP_SIM
SUBDIRS
:=
arch
/
$(ARCH)
/hp
\
$(SUBDIRS)
CORE_FILES
:=
arch
/
$(ARCH)
/hp/hp.a
\
CORE_FILES
:=
arch
/
$(ARCH)
/hp/hp.o
\
$(CORE_FILES)
endif
ifdef
CONFIG_IA64_HP_ZX1
SUBDIRS
:=
arch
/
$(ARCH)
/hp
\
arch
/
$(ARCH)
/dig
\
$(SUBDIRS)
CORE_FILES
:=
arch
/
$(ARCH)
/hp/hp.o
\
arch
/
$(ARCH)
/dig/dig.a
\
$(CORE_FILES)
endif
...
...
arch/ia64/config.in
View file @
e19f970b
...
...
@@ -22,6 +22,7 @@ choice 'IA-64 system type' \
"generic CONFIG_IA64_GENERIC \
DIG-compliant CONFIG_IA64_DIG \
HP-simulator CONFIG_IA64_HP_SIM \
HP-zx1 CONFIG_IA64_HP_ZX1 \
SGI-SN1 CONFIG_IA64_SGI_SN1 \
SGI-SN2 CONFIG_IA64_SGI_SN2" generic
...
...
@@ -56,7 +57,7 @@ if [ "$CONFIG_MCKINLEY" = "y" ]; then
fi
fi
if [ "$CONFIG_IA64_
DIG
" = "y" ]; then
if [ "$CONFIG_IA64_
GENERIC" = "y" ] || [ "$CONFIG_IA64_DIG" = "y" ] || [ "$CONFIG_IA64_HP_ZX1
" = "y" ]; then
bool ' Enable IA-64 Machine Check Abort' CONFIG_IA64_MCA
define_bool CONFIG_PM y
fi
...
...
arch/ia64/dig/setup.c
View file @
e19f970b
...
...
@@ -35,8 +35,6 @@
char
drive_info
[
4
*
16
];
extern
int
pcat_compat
;
unsigned
char
aux_device_present
=
0xaa
;
/* XXX remove this when legacy I/O is gone */
void
__init
dig_setup
(
char
**
cmdline_p
)
{
...
...
arch/ia64/hp/common/Makefile
View file @
e19f970b
...
...
@@ -12,3 +12,17 @@ export-objs := sba_iommu.o
obj-y
:=
sba_iommu.o
include
$(TOPDIR)/Rules.make
#
# ia64/platform/hp/common/Makefile
#
# Copyright (C) 2002 Hewlett Packard
# Copyright (C) Alex Williamson (alex_williamson@hp.com)
#
O_TARGET
:=
common.o
export-objs
:=
sba_iommu.o
obj-y
:=
sba_iommu.o
include
$(TOPDIR)/Rules.make
arch/ia64/hp/common/sba_iommu.c
View file @
e19f970b
This diff is collapsed.
Click to expand it.
arch/ia64/hp/sim/Makefile
View file @
e19f970b
...
...
@@ -11,3 +11,16 @@ obj-y := hpsim_console.o hpsim_irq.o hpsim_setup.o
obj-$(CONFIG_IA64_GENERIC)
+=
hpsim_machvec.o
include
$(TOPDIR)/Rules.make
#
# ia64/platform/hp/sim/Makefile
#
# Copyright (C) 1999 Silicon Graphics, Inc.
# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
#
O_TARGET
:=
sim.o
obj-y
:=
hpsim_console.o hpsim_irq.o hpsim_setup.o
obj-$(CONFIG_IA64_GENERIC)
+=
hpsim_machvec.o
include
$(TOPDIR)/Rules.make
arch/ia64/hp/hpsim_console.c
→
arch/ia64/hp/
sim/
hpsim_console.c
View file @
e19f970b
File moved
arch/ia64/hp/hpsim_irq.c
→
arch/ia64/hp/
sim/
hpsim_irq.c
View file @
e19f970b
File moved
arch/ia64/hp/hpsim_machvec.c
→
arch/ia64/hp/
sim/
hpsim_machvec.c
View file @
e19f970b
File moved
arch/ia64/hp/hpsim_setup.c
→
arch/ia64/hp/
sim/
hpsim_setup.c
View file @
e19f970b
File moved
arch/ia64/hp/hpsim_ssc.h
→
arch/ia64/hp/
sim/
hpsim_ssc.h
View file @
e19f970b
File moved
arch/ia64/hp/zx1/Makefile
View file @
e19f970b
...
...
@@ -11,3 +11,16 @@ obj-y := hpzx1_misc.o
obj-$(CONFIG_IA64_GENERIC)
+=
hpzx1_machvec.o
include
$(TOPDIR)/Rules.make
#
# ia64/platform/hp/zx1/Makefile
#
# Copyright (C) 2002 Hewlett Packard
# Copyright (C) Alex Williamson (alex_williamson@hp.com)
#
O_TARGET
:=
zx1.o
obj-y
:=
hpzx1_misc.o
obj-$(CONFIG_IA64_GENERIC)
+=
hpzx1_machvec.o
include
$(TOPDIR)/Rules.make
arch/ia64/hp/zx1/hpzx1_machvec.c
View file @
e19f970b
#define MACHVEC_PLATFORM_NAME hpzx1
#include <asm/machvec_init.h>
#define MACHVEC_PLATFORM_NAME hpzx1
#include <asm/machvec_init.h>
arch/ia64/hp/zx1/hpzx1_misc.c
View file @
e19f970b
This diff is collapsed.
Click to expand it.
arch/ia64/kernel/Makefile
View file @
e19f970b
...
...
@@ -17,6 +17,7 @@ obj-y := acpi.o entry.o gate.o efi.o efi_stub.o ia64_ksyms.o irq.o irq_ia64.o ir
machvec.o pal.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o
\
signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
obj-$(CONFIG_IA64_GENERIC)
+=
iosapic.o
obj-$(CONFIG_IA64_HP_ZX1)
+=
iosapic.o
obj-$(CONFIG_IA64_DIG)
+=
iosapic.o
obj-$(CONFIG_IA64_PALINFO)
+=
palinfo.o
obj-$(CONFIG_EFI_VARS)
+=
efivars.o
...
...
arch/ia64/kernel/acpi.c
View file @
e19f970b
...
...
@@ -23,6 +23,7 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/irq.h>
#include <linux/acpi.h>
#ifdef CONFIG_SERIAL_ACPI
#include <linux/acpi_serial.h>
#endif
...
...
@@ -58,9 +59,34 @@ asm (".weak iosapic_version");
const
char
*
acpi_get_sysname
(
void
)
{
/* the following should go away once we have an ACPI parser: */
#ifdef CONFIG_IA64_GENERIC
return
"hpsim"
;
if
(
efi
.
acpi20
)
{
acpi20_rsdp_t
*
rsdp20
;
acpi_xsdt_t
*
xsdt
;
acpi_desc_table_hdr_t
*
hdrp
;
rsdp20
=
efi
.
acpi20
;
if
(
strncmp
(
rsdp20
->
signature
,
ACPI_RSDP_SIG
,
ACPI_RSDP_SIG_LEN
))
{
printk
(
"ACPI 2.0 RSDP signature incorrect, default to DIG compatible
\n
"
);
return
"dig"
;
}
xsdt
=
__va
(
rsdp20
->
xsdt
);
hdrp
=
&
xsdt
->
header
;
if
(
strncmp
(
hdrp
->
signature
,
ACPI_XSDT_SIG
,
ACPI_XSDT_SIG_LEN
))
{
printk
(
"ACPI 2.0 XSDT signature incorrect, default to DIG compatible
\n
"
);
return
"dig"
;
}
if
(
!
strcmp
(
hdrp
->
oem_id
,
"HP"
))
{
printk
(
"Enabling Hewlett Packard zx1 chipset support
\n
"
);
return
"hpzx1"
;
}
}
return
"dig"
;
#else
# if defined (CONFIG_IA64_HP_SIM)
return
"hpsim"
;
...
...
@@ -68,13 +94,14 @@ acpi_get_sysname (void)
return
"sn1"
;
# elif defined (CONFIG_IA64_SGI_SN2)
return
"sn2"
;
# elif defined (CONFIG_IA64_HP_ZX1)
return
"hpzx1"
;
# elif defined (CONFIG_IA64_DIG)
return
"dig"
;
# else
# error Unknown platform. Fix acpi.c.
# endif
#endif
}
/*
...
...
@@ -679,3 +706,74 @@ acpi_parse (acpi_rsdp_t *rsdp)
# endif
/* CONFIG_ACPI */
return
1
;
}
#ifdef CONFIG_ACPI
#include "../drivers/acpi/include/platform/acgcc.h"
#include "../drivers/acpi/include/actypes.h"
#include "../drivers/acpi/include/acexcep.h"
#include "../drivers/acpi/include/acpixf.h"
#include "../drivers/acpi/include/actbl.h"
#include "../drivers/acpi/include/acconfig.h"
#include "../drivers/acpi/include/acmacros.h"
#include "../drivers/acpi/include/aclocal.h"
#include "../drivers/acpi/include/acobject.h"
#include "../drivers/acpi/include/acstruct.h"
#include "../drivers/acpi/include/acnamesp.h"
#include "../drivers/acpi/include/acutils.h"
/**
* acpi_get_crs - Return the current resource settings for a device
* obj: A handle for this device
* buf: A buffer to be populated by this call.
*
* Pass a valid handle, typically obtained by walking the namespace and a
* pointer to an allocated buffer, and this function will fill in the buffer
* with a list of acpi_resource structures.
*/
acpi_status
acpi_get_crs
(
acpi_handle
obj
,
acpi_buffer
*
buf
)
{
acpi_status
result
;
buf
->
length
=
0
;
buf
->
pointer
=
NULL
;
result
=
acpi_get_current_resources
(
obj
,
buf
);
if
(
result
!=
AE_BUFFER_OVERFLOW
)
return
result
;
buf
->
pointer
=
kmalloc
(
buf
->
length
,
GFP_KERNEL
);
if
(
!
buf
->
pointer
)
return
-
ENOMEM
;
result
=
acpi_get_current_resources
(
obj
,
buf
);
return
result
;
}
acpi_resource
*
acpi_get_crs_next
(
acpi_buffer
*
buf
,
int
*
offset
)
{
acpi_resource
*
res
;
if
(
*
offset
>=
buf
->
length
)
return
NULL
;
res
=
buf
->
pointer
+
*
offset
;
*
offset
+=
res
->
length
;
return
res
;
}
acpi_resource_data
*
acpi_get_crs_type
(
acpi_buffer
*
buf
,
int
*
offset
,
int
type
)
{
for
(;;)
{
acpi_resource
*
res
=
acpi_get_crs_next
(
buf
,
offset
);
if
(
!
res
)
return
NULL
;
if
(
res
->
id
==
type
)
return
&
res
->
data
;
}
}
void
acpi_dispose_crs
(
acpi_buffer
*
buf
)
{
kfree
(
buf
->
pointer
);
}
#endif
/* CONFIG_ACPI */
arch/ia64/kernel/ia64_ksyms.c
View file @
e19f970b
...
...
@@ -148,3 +148,10 @@ EXPORT_SYMBOL(efi);
#include <linux/proc_fs.h>
extern
struct
proc_dir_entry
*
efi_dir
;
EXPORT_SYMBOL
(
efi_dir
);
#include <asm/machvec.h>
#ifdef CONFIG_IA64_GENERIC
EXPORT_SYMBOL
(
ia64_mv
);
#endif
EXPORT_SYMBOL
(
machvec_noop
);
arch/ia64/kernel/irq.c
View file @
e19f970b
...
...
@@ -68,6 +68,23 @@
irq_desc_t
_irq_desc
[
NR_IRQS
]
__cacheline_aligned
=
{
[
0
...
NR_IRQS
-
1
]
=
{
IRQ_DISABLED
,
&
no_irq_type
,
NULL
,
0
,
SPIN_LOCK_UNLOCKED
}};
#ifdef CONFIG_IA64_GENERIC
struct
irq_desc
*
__ia64_irq_desc
(
unsigned
int
irq
)
{
return
_irq_desc
+
irq
;
}
ia64_vector
__ia64_irq_to_vector
(
unsigned
int
irq
)
{
return
(
ia64_vector
)
irq
;
}
unsigned
int
__ia64_local_vector_to_irq
(
ia64_vector
vec
)
{
return
(
unsigned
int
)
vec
;
}
#endif
static
void
register_irq_proc
(
unsigned
int
irq
);
/*
...
...
arch/ia64/kernel/setup.c
View file @
e19f970b
...
...
@@ -64,6 +64,8 @@ struct screen_info screen_info;
unsigned
long
ia64_iobase
;
/* virtual address for I/O accesses */
unsigned
char
aux_device_present
=
0xaa
;
/* XXX remove this when legacy I/O is gone */
#define COMMAND_LINE_SIZE 512
char
saved_command_line
[
COMMAND_LINE_SIZE
];
/* used in proc filesystem */
...
...
arch/ia64/mm/tlb.c
View file @
e19f970b
...
...
@@ -79,7 +79,7 @@ wrap_mmu_context (struct mm_struct *mm)
flush_tlb_all
();
}
static
inline
void
void
ia64_global_tlb_purge
(
unsigned
long
start
,
unsigned
long
end
,
unsigned
long
nbits
)
{
static
spinlock_t
ptcg_lock
=
SPIN_LOCK_UNLOCKED
;
...
...
drivers/pci/pci.ids
View file @
e19f970b
...
...
@@ -930,6 +930,9 @@
121a NetServer SMIC Controller
121b NetServer Legacy COM Port Decoder
121c NetServer PCI COM Port Decoder
1229 zx1 System Bus Adapter
122a zx1 I/O Controller
122e zx1 Local Bus Adapter
2910 E2910A
2925 E2925A
103e Solliday Engineering
...
...
include/asm-ia64/hw_irq.h
View file @
e19f970b
...
...
@@ -88,6 +88,7 @@ hw_resend_irq (struct hw_interrupt_type *h, unsigned int vector)
extern
struct
irq_desc
_irq_desc
[
NR_IRQS
];
#ifndef CONFIG_IA64_GENERIC
static
inline
struct
irq_desc
*
__ia64_irq_desc
(
unsigned
int
irq
)
{
...
...
@@ -105,6 +106,7 @@ __ia64_local_vector_to_irq (ia64_vector vec)
{
return
(
unsigned
int
)
vec
;
}
#endif
/*
* Next follows the irq descriptor interface. On IA-64, each CPU supports 256 interrupt
...
...
include/asm-ia64/machvec.h
View file @
e19f970b
...
...
@@ -68,6 +68,8 @@ extern void machvec_noop (void);
# include <asm/machvec_hpsim.h>
# elif defined (CONFIG_IA64_DIG)
# include <asm/machvec_dig.h>
# elif defined (CONFIG_IA64_HP_ZX1)
# include <asm/machvec_hpzx1.h>
# elif defined (CONFIG_IA64_SGI_SN1)
# include <asm/machvec_sn1.h>
# elif defined (CONFIG_IA64_SGI_SN2)
...
...
@@ -123,6 +125,7 @@ struct ia64_machine_vector {
ia64_mv_cmci_handler_t
*
cmci_handler
;
ia64_mv_log_print_t
*
log_print
;
ia64_mv_send_ipi_t
*
send_ipi
;
ia64_mv_global_tlb_purge_t
*
global_tlb_purge
;
ia64_mv_pci_dma_init
*
dma_init
;
ia64_mv_pci_alloc_consistent
*
alloc_consistent
;
ia64_mv_pci_free_consistent
*
free_consistent
;
...
...
@@ -149,6 +152,7 @@ struct ia64_machine_vector {
{ \
#name, \
platform_setup, \
platform_cpu_init, \
platform_irq_init, \
platform_pci_fixup, \
platform_map_nr, \
...
...
include/asm-ia64/machvec_hpzx1.h
View file @
e19f970b
...
...
@@ -35,3 +35,40 @@ extern ia64_mv_pci_dma_address sba_dma_address;
#define platform_pci_dma_address sba_dma_address
#endif
/* _ASM_IA64_MACHVEC_HPZX1_h */
#ifndef _ASM_IA64_MACHVEC_HPZX1_h
#define _ASM_IA64_MACHVEC_HPZX1_h
extern
ia64_mv_setup_t
dig_setup
;
extern
ia64_mv_pci_fixup_t
hpzx1_pci_fixup
;
extern
ia64_mv_map_nr_t
map_nr_dense
;
extern
ia64_mv_pci_alloc_consistent
sba_alloc_consistent
;
extern
ia64_mv_pci_free_consistent
sba_free_consistent
;
extern
ia64_mv_pci_map_single
sba_map_single
;
extern
ia64_mv_pci_unmap_single
sba_unmap_single
;
extern
ia64_mv_pci_map_sg
sba_map_sg
;
extern
ia64_mv_pci_unmap_sg
sba_unmap_sg
;
extern
ia64_mv_pci_dma_address
sba_dma_address
;
/*
* This stuff has dual use!
*
* For a generic kernel, the macros are used to initialize the
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
#define platform_name "hpzx1"
#define platform_setup dig_setup
#define platform_pci_fixup hpzx1_pci_fixup
#define platform_map_nr map_nr_dense
#define platform_pci_dma_init ((ia64_mv_pci_dma_init *) machvec_noop)
#define platform_pci_alloc_consistent sba_alloc_consistent
#define platform_pci_free_consistent sba_free_consistent
#define platform_pci_map_single sba_map_single
#define platform_pci_unmap_single sba_unmap_single
#define platform_pci_map_sg sba_map_sg
#define platform_pci_unmap_sg sba_unmap_sg
#define platform_pci_dma_sync_single ((ia64_mv_pci_dma_sync_single *) machvec_noop)
#define platform_pci_dma_sync_sg ((ia64_mv_pci_dma_sync_sg *) machvec_noop)
#define platform_pci_dma_address sba_dma_address
#endif
/* _ASM_IA64_MACHVEC_HPZX1_h */
include/asm-ia64/machvec_init.h
View file @
e19f970b
...
...
@@ -5,6 +5,11 @@
#include <asm/machvec.h>
extern
ia64_mv_send_ipi_t
ia64_send_ipi
;
extern
ia64_mv_global_tlb_purge_t
ia64_global_tlb_purge
;
extern
ia64_mv_irq_desc
__ia64_irq_desc
;
extern
ia64_mv_irq_to_vector
__ia64_irq_to_vector
;
extern
ia64_mv_local_vector_to_irq
__ia64_local_vector_to_irq
;
extern
ia64_mv_inb_t
__ia64_inb
;
extern
ia64_mv_inw_t
__ia64_inw
;
extern
ia64_mv_inl_t
__ia64_inl
;
...
...
include/linux/pci_ids.h
View file @
e19f970b
...
...
@@ -507,6 +507,9 @@
#define PCI_DEVICE_ID_HP_DIVA1 0x1049
#define PCI_DEVICE_ID_HP_DIVA2 0x104A
#define PCI_DEVICE_ID_HP_SP2_0 0x104B
#define PCI_DEVICE_ID_HP_ZX1_SBA 0x1229
#define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a
#define PCI_DEVICE_ID_HP_ZX1_LBA 0x122e
#define PCI_VENDOR_ID_PCTECH 0x1042
#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment