Commit 903d1fe4 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents fa72effd 40f911f6
......@@ -12,14 +12,16 @@
#include <asm/uaccess.h>
#include <asm/mmx.h>
static inline int movsl_is_ok(const void *a1, const void *a2, unsigned long n)
static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned long n)
{
#ifdef CONFIG_X86_INTEL_USERCOPY
if (n >= 64 && (((const long)a1 ^ (const long)a2) & movsl_mask.mask))
if (n >= 64 && ((a1 ^ a2) & movsl_mask.mask))
return 0;
#endif
return 1;
}
#define movsl_is_ok(a1,a2,n) \
__movsl_is_ok((unsigned long)(a1),(unsigned long)(a2),(n))
/*
* Copy a null terminated string from userspace.
......@@ -74,7 +76,7 @@ do { \
* and returns @count.
*/
long
__strncpy_from_user(char *dst, const char *src, long count)
__strncpy_from_user(char *dst, const char __user *src, long count)
{
long res;
__do_strncpy_from_user(dst, src, count, res);
......@@ -100,7 +102,7 @@ __strncpy_from_user(char *dst, const char *src, long count)
* and returns @count.
*/
long
strncpy_from_user(char *dst, const char *src, long count)
strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
if (access_ok(VERIFY_READ, src, 1))
......@@ -145,7 +147,7 @@ do { \
* On success, this will be zero.
*/
unsigned long
clear_user(void *to, unsigned long n)
clear_user(void __user *to, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
__do_clear_user(to, n);
......@@ -164,7 +166,7 @@ clear_user(void *to, unsigned long n)
* On success, this will be zero.
*/
unsigned long
__clear_user(void *to, unsigned long n)
__clear_user(void __user *to, unsigned long n)
{
__do_clear_user(to, n);
return n;
......@@ -181,7 +183,7 @@ __clear_user(void *to, unsigned long n)
* On exception, returns 0.
* If the string is too long, returns a value greater than @n.
*/
long strnlen_user(const char *s, long n)
long strnlen_user(const char __user *s, long n)
{
unsigned long mask = -__addr_ok(s);
unsigned long res, tmp;
......@@ -484,7 +486,7 @@ do { \
} while (0)
unsigned long __copy_to_user_ll(void *to, const void *from, unsigned long n)
unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n)
{
#ifndef CONFIG_X86_WP_WORKS_OK
if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
......@@ -534,17 +536,17 @@ unsigned long __copy_to_user_ll(void *to, const void *from, unsigned long n)
}
#endif
if (movsl_is_ok(to, from, n))
__copy_user(to, from, n);
__copy_user((void *)to, from, n);
else
n = __copy_user_intel(to, from, n);
n = __copy_user_intel((void *)to, from, n);
return n;
}
unsigned long __copy_from_user_ll(void *to, const void *from, unsigned long n)
unsigned long __copy_from_user_ll(void *to, const void __user *from, unsigned long n)
{
if (movsl_is_ok(to, from, n))
__copy_user_zeroing(to, from, n);
__copy_user_zeroing(to, (const void *) from, n);
else
n = __copy_user_zeroing_intel(to, from, n);
n = __copy_user_zeroing_intel(to, (const void *) from, n);
return n;
}
agpgart-y := backend.o frontend.o generic.o generic-3.0.o
agpgart-y := backend.o frontend.o generic.o isoch.o
obj-$(CONFIG_AGP) += agpgart.o
obj-$(CONFIG_AGP_ALI) += ali-agp.o
......
......@@ -139,6 +139,8 @@ struct agp_bridge_data {
int max_memory_agp; /* in number of pages */
int aperture_size_idx;
int capndx;
char major_version;
char minor_version;
};
#define OUTREG64(mmap, addr, val) __raw_writeq((val), (mmap)+(addr))
......@@ -388,27 +390,38 @@ void agp_free_key(int key);
int agp_num_entries(void);
u32 agp_collect_device_status(u32 mode, u32 command);
void agp_device_command(u32 command, int agp_v3);
int agp_3_0_node_enable(struct agp_bridge_data *bridge, u32 mode, u32 minor);
int agp_3_0_enable(struct agp_bridge_data *bridge, u32 mode);
int agp_3_5_enable(struct agp_bridge_data *bridge, u32 mode);
void global_cache_flush(void);
void get_agp_version(struct agp_bridge_data *bridge);
/* Standard agp registers */
#define AGPSTAT 0x4
#define AGPCMD 0x8
#define AGPNISTAT 0xc
#define AGPNEPG 0x16
#define AGPNICMD 0x20
#define AGP_MAJOR_VERSION_SHIFT (20)
#define AGP_MINOR_VERSION_SHIFT (16)
#define AGPSTAT_RQ_DEPTH (0xff000000)
#define AGPSTAT_CAL_MASK (1<<12|1<<11|1<<10)
#define AGPSTAT_ARQSZ (1<<15|1<<14|1<<13)
#define AGPSTAT_ARQSZ_SHIFT 13
#define AGPSTAT_AGP_ENABLE (1<<8)
#define AGPSTAT_SBA (1<<9)
#define AGPSTAT_AGP_ENABLE (1<<8)
#define AGPSTAT_FW (1<<4)
#define AGPSTAT_MODE_3_0 (1<<3)
#define AGPSTAT2_1X (1<<0)
#define AGPSTAT2_2X (1<<1)
#define AGPSTAT2_4X (1<<2)
#define AGPSTAT_FW (1<<4)
#define AGPSTAT3_RSVD (1<<2)
#define AGPSTAT3_8X (1<<1)
#define AGPSTAT3_4X (1)
#endif /* _AGP_BACKEND_PRIV_H */
......@@ -253,8 +253,10 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
{
struct agp_bridge_data *bridge;
struct pci_dev *loop_dev;
u8 rev_id;
u8 cap_ptr;
int i = 0;
char *revstring=" ";
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
......@@ -266,14 +268,38 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
if (!bridge)
return -ENOMEM;
/* Assume here we have an 8151. (Later this assumption will be fixed). */
pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
switch (rev_id) {
case 0x01: revstring="A0";
break;
case 0x02: revstring="A1";
break;
case 0x11: revstring="B0";
break;
case 0x12: revstring="B1";
break;
case 0x13: revstring="B2";
break;
default: revstring="??";
break;
}
printk ("Detected AMD 8151 AGP Bridge rev %s", revstring);
/*
* Work around errata.
* Chips before B2 stepping incorrectly reporting v3.5
*/
if (rev_id < 0x13) {
bridge->major_version = 3;
bridge->minor_version = 0;
}
bridge->driver = &amd_8151_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
/* cache pci_devs of northbridges. */
pci_for_each_dev(loop_dev) {
......@@ -290,7 +316,7 @@ static int __init agp_amdk8_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
out_free:
out_free:
agp_put_bridge(bridge);
return -ENOMEM;
}
......
......@@ -270,14 +270,16 @@ EXPORT_SYMBOL_GPL(agp_num_entries);
int agp_copy_info(agp_kern_info * info)
{
memset(info, 0, sizeof(agp_kern_info));
if (agp_bridge->type == NOT_SUPPORTED) {
info->chipset = agp_bridge->type;
if (!agp_bridge || agp_bridge->type == NOT_SUPPORTED ||
!agp_bridge->version) {
info->chipset = NOT_SUPPORTED;
return -EIO;
}
info->version.major = agp_bridge->version->major;
info->version.minor = agp_bridge->version->minor;
info->device = agp_bridge->dev;
info->chipset = agp_bridge->type;
info->device = agp_bridge->dev;
info->mode = agp_bridge->mode;
info->aper_base = agp_bridge->gart_bus_addr;
info->aper_size = agp_return_size();
......@@ -366,60 +368,106 @@ EXPORT_SYMBOL(agp_unbind_memory);
/* Generic Agp routines - Start */
static void agp_v2_parse_one(u32 *mode, u32 *cmd, u32 *tmp)
{
/* disable SBA if it's not supported */
if (!((*cmd & AGPSTAT_SBA) && (*tmp & AGPSTAT_SBA) && (*mode & AGPSTAT_SBA)))
*cmd &= ~AGPSTAT_SBA;
/* disable FW if it's not supported */
if (!((*cmd & AGPSTAT_FW) && (*tmp & AGPSTAT_FW) && (*mode & AGPSTAT_FW)))
*cmd &= ~AGPSTAT_FW;
/* Set speed */
if (!((*cmd & AGPSTAT2_4X) && (*tmp & AGPSTAT2_4X) && (*mode & AGPSTAT2_4X)))
*cmd &= ~AGPSTAT2_4X;
if (!((*cmd & AGPSTAT2_2X) && (*tmp & AGPSTAT2_2X) && (*mode & AGPSTAT2_2X)))
*cmd &= ~AGPSTAT2_2X;
if (!((*cmd & AGPSTAT2_1X) && (*tmp & AGPSTAT2_1X) && (*mode & AGPSTAT2_1X)))
*cmd &= ~AGPSTAT2_1X;
/* Now we know what mode it should be, clear out the unwanted bits. */
if (*cmd & AGPSTAT2_4X)
*cmd &= ~(AGPSTAT2_1X | AGPSTAT2_2X); /* 4X */
if (*cmd & AGPSTAT2_2X)
*cmd &= ~(AGPSTAT2_1X | AGPSTAT2_4X); /* 2X */
if (*cmd & AGPSTAT2_1X)
*cmd &= ~(AGPSTAT2_2X | AGPSTAT2_4X); /* 1Xf */
}
u32 agp_collect_device_status(u32 mode, u32 command)
static void agp_v3_parse_one(u32 *mode, u32 *cmd, u32 *tmp)
{
/* ARQSZ - Set the value to the maximum one.
* Don't allow the mode register to override values. */
*cmd = ((*cmd & ~AGPSTAT_ARQSZ) |
max_t(u32,(*cmd & AGPSTAT_ARQSZ),(*tmp & AGPSTAT_ARQSZ)));
/* Calibration cycle.
* Don't allow the mode register to override values. */
*cmd = ((*cmd & ~AGPSTAT_CAL_MASK) |
min_t(u32,(*cmd & AGPSTAT_CAL_MASK),(*tmp & AGPSTAT_CAL_MASK)));
/* SBA *must* be supported for AGP v3 */
*cmd |= AGPSTAT_SBA;
/* disable FW if it's not supported */
if (!((*cmd & AGPSTAT_FW) && (*tmp & AGPSTAT_FW) && (*mode & AGPSTAT_FW)))
*cmd &= ~AGPSTAT_FW;
/* Set speed. */
if (!((*cmd & AGPSTAT3_8X) && (*tmp & AGPSTAT3_8X) && (*mode & AGPSTAT3_8X)))
*cmd &= ~AGPSTAT3_8X;
if (!((*cmd & AGPSTAT3_4X) && (*tmp & AGPSTAT3_4X) && (*mode & AGPSTAT3_4X)))
*cmd &= ~AGPSTAT3_4X;
/* Clear out unwanted bits. */
if (*cmd & AGPSTAT3_8X)
*cmd *= ~(AGPSTAT3_4X | AGPSTAT3_RSVD);
if (*cmd & AGPSTAT3_4X)
*cmd *= ~(AGPSTAT3_8X | AGPSTAT3_RSVD);
}
//FIXME: This doesn't smell right.
//We need a function we pass an agp_device to.
u32 agp_collect_device_status(u32 mode, u32 cmd)
{
struct pci_dev *device;
u8 agp;
u32 scratch;
u8 cap_ptr;
u32 tmp;
u32 agp3;
pci_for_each_dev(device) {
agp = pci_find_capability(device, PCI_CAP_ID_AGP);
if (!agp)
cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
if (!cap_ptr)
continue;
/*
* Ok, here we have a AGP device. Disable impossible
* settings, and adjust the readqueue to the minimum.
*/
pci_read_config_dword(device, agp + PCI_AGP_STATUS, &scratch);
pci_read_config_dword(device, cap_ptr+PCI_AGP_STATUS, &tmp);
/* adjust RQ depth */
command = ((command & ~AGPSTAT_RQ_DEPTH) |
cmd = ((cmd & ~AGPSTAT_RQ_DEPTH) |
min_t(u32, (mode & AGPSTAT_RQ_DEPTH),
min_t(u32, (command & AGPSTAT_RQ_DEPTH),
(scratch & AGPSTAT_RQ_DEPTH))));
/* disable SBA if it's not supported */
if (!((command & AGPSTAT_SBA) && (scratch & AGPSTAT_SBA) && (mode & AGPSTAT_SBA)))
command &= ~AGPSTAT_SBA;
/* disable FW if it's not supported */
if (!((command & AGPSTAT_FW) && (scratch & AGPSTAT_FW) && (mode & AGPSTAT_FW)))
command &= ~AGPSTAT_FW;
/* Set speed */
if (!((command & AGPSTAT2_4X) && (scratch & AGPSTAT2_4X) && (mode & AGPSTAT2_4X)))
command &= ~AGPSTAT2_4X;
min_t(u32, (cmd & AGPSTAT_RQ_DEPTH), (tmp & AGPSTAT_RQ_DEPTH))));
pci_read_config_dword(device, cap_ptr+AGPSTAT, &agp3);
if (!((command & AGPSTAT2_2X) && (scratch & AGPSTAT2_2X) && (mode & AGPSTAT2_2X)))
command &= ~AGPSTAT2_2X;
if (!((command & AGPSTAT2_1X) && (scratch & AGPSTAT2_1X) && (mode & AGPSTAT2_1X)))
command &= ~AGPSTAT2_1X;
/* Check to see if we are operating in 3.0 mode */
if (agp3 & AGPSTAT_MODE_3_0) {
agp_v3_parse_one(&mode, &cmd, &tmp);
} else {
agp_v2_parse_one(&mode, &cmd, &tmp);
}
}
/* Now we know what mode it should be, clear out the unwanted bits. */
if (command & AGPSTAT2_4X)
command &= ~(AGPSTAT2_1X | AGPSTAT2_2X); /* 4X */
if (command & AGPSTAT2_2X)
command &= ~(AGPSTAT2_1X | AGPSTAT2_4X); /* 2X */
if (command & AGPSTAT2_1X)
command &= ~(AGPSTAT2_2X | AGPSTAT2_4X); /* 1Xf */
return command;
return cmd;
}
EXPORT_SYMBOL(agp_collect_device_status);
......@@ -446,29 +494,33 @@ void agp_device_command(u32 command, int agp_v3)
EXPORT_SYMBOL(agp_device_command);
void agp_generic_enable(u32 mode)
void get_agp_version(struct agp_bridge_data *bridge)
{
u32 command, ncapid, major, minor;
u32 ncapid;
/* Exit early if already set by errata workarounds. */
if (agp_bridge->major_version != 0)
return;
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx, &ncapid);
major = (ncapid >> 20) & 0xf;
minor = (ncapid >> 16) & 0xf;
printk(KERN_INFO PFX "Found an AGP %d.%d compliant device.\n",major, minor);
agp_bridge->major_version = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
agp_bridge->minor_version = (ncapid >> AGP_MINOR_VERSION_SHIFT) & 0xf;
}
EXPORT_SYMBOL(get_agp_version);
if(major >= 3) {
u32 agp_3_0;
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x4, &agp_3_0);
/* Check to see if we are operating in 3.0 mode */
if((agp_3_0 >> 3) & 0x1) {
agp_3_0_node_enable(agp_bridge, mode, minor);
return;
} else {
printk (KERN_INFO PFX "not in AGP 3.0 mode, falling back to 2.x\n");
}
}
void agp_generic_enable(u32 mode)
{
u32 command;
u32 agp3;
get_agp_version(agp_bridge);
printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n",
agp_bridge->major_version,
agp_bridge->minor_version,
agp_bridge->dev->slot_name);
/* AGP v<3 */
pci_read_config_dword(agp_bridge->dev,
agp_bridge->capndx + PCI_AGP_STATUS, &command);
......@@ -477,7 +529,27 @@ void agp_generic_enable(u32 mode)
pci_write_config_dword(agp_bridge->dev,
agp_bridge->capndx + PCI_AGP_COMMAND, command);
agp_device_command(command, 0);
/* Do AGP version specific frobbing. */
if(agp_bridge->major_version >= 3) {
pci_read_config_dword(agp_bridge->dev,
agp_bridge->capndx+AGPSTAT, &agp3);
/* Check to see if we are operating in 3.0 mode */
if (agp3 & AGPSTAT_MODE_3_0) {
/* If we have 3.5, we can do the isoch stuff. */
if (agp_bridge->minor_version >= 5)
agp_3_5_enable(agp_bridge, mode);
agp_device_command(command, TRUE);
return;
} else {
printk (KERN_INFO PFX "Device is in legacy mode,"
" falling back to 2.x\n");
}
}
/* AGP v<3 */
agp_device_command(command, FALSE);
}
EXPORT_SYMBOL(agp_generic_enable);
......@@ -831,6 +903,7 @@ void agp_enable(u32 mode)
}
EXPORT_SYMBOL(agp_enable);
#ifdef CONFIG_SMP
static void ipi_handler(void *null)
{
......
......@@ -49,7 +49,7 @@ config DRM_RADEON
config DRM_I810
tristate "Intel I810"
depends on DRM && AGP
depends on DRM && AGP && AGP_INTEL
help
Choose this option if you have an Intel I810 graphics card. If M is
selected, the module will be called i810. AGP support is required
......@@ -57,7 +57,7 @@ config DRM_I810
config DRM_I830
tristate "Intel 830M, 845G, 852GM, 855GM, 865G"
depends on DRM && AGP
depends on DRM && AGP && AGP_INTEL
help
Choose this option if you have a system that has Intel 830M, 845G,
852GM, 855GM or 865G integrated graphics. If M is selected, the
......
......@@ -158,7 +158,7 @@ extern int snd_seq_create_kernel_client(snd_card_t *card, int client_index, snd_
extern int snd_seq_delete_kernel_client(int client);
extern int snd_seq_kernel_client_enqueue(int client, snd_seq_event_t *ev, int atomic, int hop);
extern int snd_seq_kernel_client_dispatch(int client, snd_seq_event_t *ev, int atomic, int hop);
extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void *arg);
extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void __user *arg);
#define SNDRV_SEQ_EXT_MASK 0xc0000000
#define SNDRV_SEQ_EXT_USRPTR 0x80000000
......
......@@ -135,8 +135,8 @@ int snd_seq_oss_delete_client(void);
int snd_seq_oss_open(struct file *file, int level);
void snd_seq_oss_release(seq_oss_devinfo_t *dp);
int snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long arg);
int snd_seq_oss_read(seq_oss_devinfo_t *dev, char *buf, int count);
int snd_seq_oss_write(seq_oss_devinfo_t *dp, const char *buf, int count, struct file *opt);
int snd_seq_oss_read(seq_oss_devinfo_t *dev, char __user *buf, int count);
int snd_seq_oss_write(seq_oss_devinfo_t *dp, const char __user *buf, int count, struct file *opt);
unsigned int snd_seq_oss_poll(seq_oss_devinfo_t *dp, struct file *file, poll_table * wait);
void snd_seq_oss_reset(seq_oss_devinfo_t *dp);
......
......@@ -35,7 +35,7 @@ snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg)
struct synth_info inf;
struct midi_info minf;
unsigned char ev[8];
void *arg = (void*)carg;
void __user *arg = (void __user *)carg;
snd_seq_event_t tmpev;
switch (cmd) {
......
......@@ -41,7 +41,7 @@ static int insert_queue(seq_oss_devinfo_t *dp, evrec_t *rec, struct file *opt);
*/
int
snd_seq_oss_read(seq_oss_devinfo_t *dp, char *buf, int count)
snd_seq_oss_read(seq_oss_devinfo_t *dp, char __user *buf, int count)
{
seq_oss_readq_t *readq = dp->readq;
int cnt, pos;
......@@ -81,7 +81,7 @@ snd_seq_oss_read(seq_oss_devinfo_t *dp, char *buf, int count)
*/
int
snd_seq_oss_write(seq_oss_devinfo_t *dp, const char *buf, int count, struct file *opt)
snd_seq_oss_write(seq_oss_devinfo_t *dp, const char __user *buf, int count, struct file *opt)
{
int rc, c, p, ev_size;
evrec_t rec;
......
......@@ -450,7 +450,7 @@ snd_seq_oss_synth_reset(seq_oss_devinfo_t *dp, int dev)
*/
int
snd_seq_oss_synth_load_patch(seq_oss_devinfo_t *dp, int dev, int fmt,
const char *buf, int p, int c)
const char __user *buf, int p, int c)
{
seq_oss_synth_t *rec;
int rc;
......
......@@ -227,19 +227,19 @@ snd_seq_oss_timer_tempo(seq_oss_timer_t *timer, int value)
* ioctls
*/
int
snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, void *arg)
snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, int __user *arg)
{
int value;
if (cmd == SNDCTL_SEQ_CTRLRATE) {
debug_printk(("ctrl rate\n"));
/* if *arg == 0, just return the current rate */
if (get_user(value, (int *)arg))
if (get_user(value, arg))
return -EFAULT;
if (value)
return -EINVAL;
value = ((timer->oss_tempo * timer->oss_timebase) + 30) / 60;
return put_user(value, (int *)arg) ? -EFAULT : 0;
return put_user(value, arg) ? -EFAULT : 0;
}
if (timer->dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH)
......@@ -257,12 +257,12 @@ snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, void *arg)
return snd_seq_oss_timer_continue(timer);
case SNDCTL_TMR_TEMPO:
debug_printk(("timer tempo\n"));
if (get_user(value, (int *)arg))
if (get_user(value, arg))
return -EFAULT;
return snd_seq_oss_timer_tempo(timer, value);
case SNDCTL_TMR_TIMEBASE:
debug_printk(("timer timebase\n"));
if (get_user(value, (int *)arg))
if (get_user(value, arg))
return -EFAULT;
if (value < MIN_OSS_TIMEBASE)
value = MIN_OSS_TIMEBASE;
......
......@@ -46,7 +46,7 @@ int snd_seq_oss_timer_continue(seq_oss_timer_t *timer);
int snd_seq_oss_timer_tempo(seq_oss_timer_t *timer, int value);
#define snd_seq_oss_timer_reset snd_seq_oss_timer_start
int snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, void *arg);
int snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, int __user *arg);
/*
* get current processed time
......
This diff is collapsed.
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