Commit 49b7466c authored by Alexander Viro's avatar Alexander Viro Committed by Jeff Garzik

[PATCH] killed isa_... in 3c507

switched to ioremap() + normal read../write..
Signed-off-by: default avatarAl Viro <viro@parcelfarce.linux.theplanet.co.uk>
parent 6ce9fa37
...@@ -127,6 +127,7 @@ struct net_local { ...@@ -127,6 +127,7 @@ struct net_local {
ushort tx_reap; ushort tx_reap;
ushort tx_pkts_in_ring; ushort tx_pkts_in_ring;
spinlock_t lock; spinlock_t lock;
void __iomem *base;
}; };
/* /*
...@@ -348,6 +349,7 @@ struct net_device * __init el16_probe(int unit) ...@@ -348,6 +349,7 @@ struct net_device * __init el16_probe(int unit)
return dev; return dev;
out1: out1:
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
iounmap(((struct net_local *)netdev_priv(dev))->base);
release_region(dev->base_addr, EL16_IO_EXTENT); release_region(dev->base_addr, EL16_IO_EXTENT);
out: out:
free_netdev(dev); free_netdev(dev);
...@@ -395,7 +397,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) ...@@ -395,7 +397,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev); irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
if (irqval) { if (irqval) {
printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval); printk(KERN_ERR "3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
retval = -EAGAIN; retval = -EAGAIN;
goto out; goto out;
} }
...@@ -445,6 +447,12 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) ...@@ -445,6 +447,12 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
lp = netdev_priv(dev); lp = netdev_priv(dev);
memset(lp, 0, sizeof(*lp)); memset(lp, 0, sizeof(*lp));
spin_lock_init(&lp->lock); spin_lock_init(&lp->lock);
lp->base = ioremap(dev->mem_start, RX_BUF_END);
if (!lp->base) {
printk(KERN_ERR "3c507: unable to remap memory\n");
retval = -EAGAIN;
goto out1;
}
dev->open = el16_open; dev->open = el16_open;
dev->stop = el16_close; dev->stop = el16_close;
...@@ -455,6 +463,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr) ...@@ -455,6 +463,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
dev->ethtool_ops = &netdev_ethtool_ops; dev->ethtool_ops = &netdev_ethtool_ops;
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */ dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
return 0; return 0;
out1:
free_irq(dev->irq, dev);
out: out:
release_region(ioaddr, EL16_IO_EXTENT); release_region(ioaddr, EL16_IO_EXTENT);
return retval; return retval;
...@@ -474,11 +484,11 @@ static void el16_tx_timeout (struct net_device *dev) ...@@ -474,11 +484,11 @@ static void el16_tx_timeout (struct net_device *dev)
{ {
struct net_local *lp = netdev_priv(dev); struct net_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
unsigned long shmem = dev->mem_start; void __iomem *shmem = lp->base;
if (net_debug > 1) if (net_debug > 1)
printk ("%s: transmit timed out, %s? ", dev->name, printk ("%s: transmit timed out, %s? ", dev->name,
isa_readw (shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" : readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
"network cable problem"); "network cable problem");
/* Try to restart the adaptor. */ /* Try to restart the adaptor. */
if (lp->last_restart == lp->stats.tx_packets) { if (lp->last_restart == lp->stats.tx_packets) {
...@@ -491,7 +501,7 @@ static void el16_tx_timeout (struct net_device *dev) ...@@ -491,7 +501,7 @@ static void el16_tx_timeout (struct net_device *dev)
/* Issue the channel attention signal and hope it "gets better". */ /* Issue the channel attention signal and hope it "gets better". */
if (net_debug > 1) if (net_debug > 1)
printk ("Kicking board.\n"); printk ("Kicking board.\n");
isa_writew (0xf000 | CUC_START | RX_START, shmem + iSCB_CMD); writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */ outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
lp->last_restart = lp->stats.tx_packets; lp->last_restart = lp->stats.tx_packets;
} }
...@@ -539,7 +549,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -539,7 +549,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct net_local *lp; struct net_local *lp;
int ioaddr, status, boguscount = 0; int ioaddr, status, boguscount = 0;
ushort ack_cmd = 0; ushort ack_cmd = 0;
unsigned long shmem; void __iomem *shmem;
if (dev == NULL) { if (dev == NULL) {
printk ("net_interrupt(): irq %d for unknown device.\n", irq); printk ("net_interrupt(): irq %d for unknown device.\n", irq);
...@@ -548,11 +558,11 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -548,11 +558,11 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ioaddr = dev->base_addr; ioaddr = dev->base_addr;
lp = netdev_priv(dev); lp = netdev_priv(dev);
shmem = dev->mem_start; shmem = lp->base;
spin_lock(&lp->lock); spin_lock(&lp->lock);
status = isa_readw(shmem+iSCB_STATUS); status = readw(shmem+iSCB_STATUS);
if (net_debug > 4) { if (net_debug > 4) {
printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status); printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
...@@ -563,7 +573,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -563,7 +573,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* Reap the Tx packet buffers. */ /* Reap the Tx packet buffers. */
while (lp->tx_pkts_in_ring) { while (lp->tx_pkts_in_ring) {
unsigned short tx_status = isa_readw(shmem+lp->tx_reap); unsigned short tx_status = readw(shmem+lp->tx_reap);
if (!(tx_status & 0x8000)) { if (!(tx_status & 0x8000)) {
if (net_debug > 5) if (net_debug > 5)
printk("Tx command incomplete (%#x).\n", lp->tx_reap); printk("Tx command incomplete (%#x).\n", lp->tx_reap);
...@@ -619,11 +629,11 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -619,11 +629,11 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
printk("%s: Rx unit stopped, status %04x, restarting.\n", printk("%s: Rx unit stopped, status %04x, restarting.\n",
dev->name, status); dev->name, status);
init_rx_bufs(dev); init_rx_bufs(dev);
isa_writew(RX_BUF_START,shmem+iSCB_RFA); writew(RX_BUF_START,shmem+iSCB_RFA);
ack_cmd |= RX_START; ack_cmd |= RX_START;
} }
isa_writew(ack_cmd,shmem+iSCB_CMD); writew(ack_cmd,shmem+iSCB_CMD);
outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */ outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
/* Clear the latched interrupt. */ /* Clear the latched interrupt. */
...@@ -637,13 +647,14 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -637,13 +647,14 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static int el16_close(struct net_device *dev) static int el16_close(struct net_device *dev)
{ {
struct net_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr; int ioaddr = dev->base_addr;
unsigned long shmem = dev->mem_start; void __iomem *shmem = lp->base;
netif_stop_queue(dev); netif_stop_queue(dev);
/* Flush the Tx and disable Rx. */ /* Flush the Tx and disable Rx. */
isa_writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD); writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD);
outb(0, ioaddr + SIGNAL_CA); outb(0, ioaddr + SIGNAL_CA);
/* Disable the 82586's input to the interrupt line. */ /* Disable the 82586's input to the interrupt line. */
...@@ -671,7 +682,7 @@ static struct net_device_stats *el16_get_stats(struct net_device *dev) ...@@ -671,7 +682,7 @@ static struct net_device_stats *el16_get_stats(struct net_device *dev)
static void init_rx_bufs(struct net_device *dev) static void init_rx_bufs(struct net_device *dev)
{ {
struct net_local *lp = netdev_priv(dev); struct net_local *lp = netdev_priv(dev);
unsigned long write_ptr; void __iomem *write_ptr;
unsigned short SCB_base = SCB_BASE; unsigned short SCB_base = SCB_BASE;
int cur_rxbuf = lp->rx_head = RX_BUF_START; int cur_rxbuf = lp->rx_head = RX_BUF_START;
...@@ -679,26 +690,26 @@ static void init_rx_bufs(struct net_device *dev) ...@@ -679,26 +690,26 @@ static void init_rx_bufs(struct net_device *dev)
/* Initialize each Rx frame + data buffer. */ /* Initialize each Rx frame + data buffer. */
do { /* While there is room for one more. */ do { /* While there is room for one more. */
write_ptr = dev->mem_start + cur_rxbuf; write_ptr = lp->base + cur_rxbuf;
isa_writew(0x0000,write_ptr); /* Status */ writew(0x0000,write_ptr); /* Status */
isa_writew(0x0000,write_ptr+=2); /* Command */ writew(0x0000,write_ptr+=2); /* Command */
isa_writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2); /* Link */ writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2); /* Link */
isa_writew(cur_rxbuf + 22,write_ptr+=2); /* Buffer offset */ writew(cur_rxbuf + 22,write_ptr+=2); /* Buffer offset */
isa_writew(0x0000,write_ptr+=2); /* Pad for dest addr. */ writew(0x0000,write_ptr+=2); /* Pad for dest addr. */
isa_writew(0x0000,write_ptr+=2); writew(0x0000,write_ptr+=2);
isa_writew(0x0000,write_ptr+=2); writew(0x0000,write_ptr+=2);
isa_writew(0x0000,write_ptr+=2); /* Pad for source addr. */ writew(0x0000,write_ptr+=2); /* Pad for source addr. */
isa_writew(0x0000,write_ptr+=2); writew(0x0000,write_ptr+=2);
isa_writew(0x0000,write_ptr+=2); writew(0x0000,write_ptr+=2);
isa_writew(0x0000,write_ptr+=2); /* Pad for protocol. */ writew(0x0000,write_ptr+=2); /* Pad for protocol. */
isa_writew(0x0000,write_ptr+=2); /* Buffer: Actual count */ writew(0x0000,write_ptr+=2); /* Buffer: Actual count */
isa_writew(-1,write_ptr+=2); /* Buffer: Next (none). */ writew(-1,write_ptr+=2); /* Buffer: Next (none). */
isa_writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */ writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */
isa_writew(0x0000,write_ptr+=2); writew(0x0000,write_ptr+=2);
/* Finally, the number of bytes in the buffer. */ /* Finally, the number of bytes in the buffer. */
isa_writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2); writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2);
lp->rx_tail = cur_rxbuf; lp->rx_tail = cur_rxbuf;
cur_rxbuf += RX_BUF_SIZE; cur_rxbuf += RX_BUF_SIZE;
...@@ -706,16 +717,16 @@ static void init_rx_bufs(struct net_device *dev) ...@@ -706,16 +717,16 @@ static void init_rx_bufs(struct net_device *dev)
/* Terminate the list by setting the EOL bit, and wrap the pointer to make /* Terminate the list by setting the EOL bit, and wrap the pointer to make
the list a ring. */ the list a ring. */
write_ptr = dev->mem_start + lp->rx_tail + 2; write_ptr = lp->base + lp->rx_tail + 2;
isa_writew(0xC000,write_ptr); /* Command, mark as last. */ writew(0xC000,write_ptr); /* Command, mark as last. */
isa_writew(lp->rx_head,write_ptr+2); /* Link */ writew(lp->rx_head,write_ptr+2); /* Link */
} }
static void init_82586_mem(struct net_device *dev) static void init_82586_mem(struct net_device *dev)
{ {
struct net_local *lp = netdev_priv(dev); struct net_local *lp = netdev_priv(dev);
short ioaddr = dev->base_addr; short ioaddr = dev->base_addr;
unsigned long shmem = dev->mem_start; void __iomem *shmem = lp->base;
/* Enable loopback to protect the wire while starting up, /* Enable loopback to protect the wire while starting up,
and hold the 586 in reset during the memory initialization. */ and hold the 586 in reset during the memory initialization. */
...@@ -726,13 +737,13 @@ static void init_82586_mem(struct net_device *dev) ...@@ -726,13 +737,13 @@ static void init_82586_mem(struct net_device *dev)
init_words[7] = SCB_BASE; init_words[7] = SCB_BASE;
/* Write the words at 0xfff6 (address-aliased to 0xfffff6). */ /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */
isa_memcpy_toio(dev->mem_end-10, init_words, 10); memcpy_toio(lp->base + RX_BUF_END - 10, init_words, 10);
/* Write the words at 0x0000. */ /* Write the words at 0x0000. */
isa_memcpy_toio(dev->mem_start, init_words + 5, sizeof(init_words) - 10); memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10);
/* Fill in the station address. */ /* Fill in the station address. */
isa_memcpy_toio(dev->mem_start+SA_OFFSET, dev->dev_addr, memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr,
sizeof(dev->dev_addr)); sizeof(dev->dev_addr));
/* The Tx-block list is written as needed. We just set up the values. */ /* The Tx-block list is written as needed. We just set up the values. */
...@@ -750,11 +761,11 @@ static void init_82586_mem(struct net_device *dev) ...@@ -750,11 +761,11 @@ static void init_82586_mem(struct net_device *dev)
{ {
int boguscnt = 50; int boguscnt = 50;
while (isa_readw(shmem+iSCB_STATUS) == 0) while (readw(shmem+iSCB_STATUS) == 0)
if (--boguscnt == 0) { if (--boguscnt == 0) {
printk("%s: i82586 initialization timed out with status %04x," printk("%s: i82586 initialization timed out with status %04x,"
"cmd %04x.\n", dev->name, "cmd %04x.\n", dev->name,
isa_readw(shmem+iSCB_STATUS), isa_readw(shmem+iSCB_CMD)); readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
break; break;
} }
/* Issue channel-attn -- the 82586 won't start. */ /* Issue channel-attn -- the 82586 won't start. */
...@@ -765,7 +776,7 @@ static void init_82586_mem(struct net_device *dev) ...@@ -765,7 +776,7 @@ static void init_82586_mem(struct net_device *dev)
outb(0x84, ioaddr + MISC_CTRL); outb(0x84, ioaddr + MISC_CTRL);
if (net_debug > 4) if (net_debug > 4)
printk("%s: Initialized 82586, status %04x.\n", dev->name, printk("%s: Initialized 82586, status %04x.\n", dev->name,
isa_readw(shmem+iSCB_STATUS)); readw(shmem+iSCB_STATUS));
return; return;
} }
...@@ -774,33 +785,33 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length ...@@ -774,33 +785,33 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length
struct net_local *lp = netdev_priv(dev); struct net_local *lp = netdev_priv(dev);
short ioaddr = dev->base_addr; short ioaddr = dev->base_addr;
ushort tx_block = lp->tx_head; ushort tx_block = lp->tx_head;
unsigned long write_ptr = dev->mem_start + tx_block; void __iomem *write_ptr = lp->base + tx_block;
static char padding[ETH_ZLEN]; static char padding[ETH_ZLEN];
/* Set the write pointer to the Tx block, and put out the header. */ /* Set the write pointer to the Tx block, and put out the header. */
isa_writew(0x0000,write_ptr); /* Tx status */ writew(0x0000,write_ptr); /* Tx status */
isa_writew(CMD_INTR|CmdTx,write_ptr+=2); /* Tx command */ writew(CMD_INTR|CmdTx,write_ptr+=2); /* Tx command */
isa_writew(tx_block+16,write_ptr+=2); /* Next command is a NoOp. */ writew(tx_block+16,write_ptr+=2); /* Next command is a NoOp. */
isa_writew(tx_block+8,write_ptr+=2); /* Data Buffer offset. */ writew(tx_block+8,write_ptr+=2); /* Data Buffer offset. */
/* Output the data buffer descriptor. */ /* Output the data buffer descriptor. */
isa_writew((pad + length) | 0x8000,write_ptr+=2); /* Byte count parameter. */ writew((pad + length) | 0x8000,write_ptr+=2); /* Byte count parameter. */
isa_writew(-1,write_ptr+=2); /* No next data buffer. */ writew(-1,write_ptr+=2); /* No next data buffer. */
isa_writew(tx_block+22+SCB_BASE,write_ptr+=2); /* Buffer follows the NoOp command. */ writew(tx_block+22+SCB_BASE,write_ptr+=2); /* Buffer follows the NoOp command. */
isa_writew(0x0000,write_ptr+=2); /* Buffer address high bits (always zero). */ writew(0x0000,write_ptr+=2); /* Buffer address high bits (always zero). */
/* Output the Loop-back NoOp command. */ /* Output the Loop-back NoOp command. */
isa_writew(0x0000,write_ptr+=2); /* Tx status */ writew(0x0000,write_ptr+=2); /* Tx status */
isa_writew(CmdNOp,write_ptr+=2); /* Tx command */ writew(CmdNOp,write_ptr+=2); /* Tx command */
isa_writew(tx_block+16,write_ptr+=2); /* Next is myself. */ writew(tx_block+16,write_ptr+=2); /* Next is myself. */
/* Output the packet at the write pointer. */ /* Output the packet at the write pointer. */
isa_memcpy_toio(write_ptr+2, buf, length); memcpy_toio(write_ptr+2, buf, length);
if (pad) if (pad)
isa_memcpy_toio(write_ptr+length+2, padding, pad); memcpy_toio(write_ptr+length+2, padding, pad);
/* Set the old command link pointing to this send packet. */ /* Set the old command link pointing to this send packet. */
isa_writew(tx_block,dev->mem_start + lp->tx_cmd_link); writew(tx_block,lp->base + lp->tx_cmd_link);
lp->tx_cmd_link = tx_block + 20; lp->tx_cmd_link = tx_block + 20;
/* Set the next free tx region. */ /* Set the next free tx region. */
...@@ -821,19 +832,19 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length ...@@ -821,19 +832,19 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length
static void el16_rx(struct net_device *dev) static void el16_rx(struct net_device *dev)
{ {
struct net_local *lp = netdev_priv(dev); struct net_local *lp = netdev_priv(dev);
unsigned long shmem = dev->mem_start; void __iomem *shmem = lp->base;
ushort rx_head = lp->rx_head; ushort rx_head = lp->rx_head;
ushort rx_tail = lp->rx_tail; ushort rx_tail = lp->rx_tail;
ushort boguscount = 10; ushort boguscount = 10;
short frame_status; short frame_status;
while ((frame_status = isa_readw(shmem+rx_head)) < 0) { /* Command complete */ while ((frame_status = readw(shmem+rx_head)) < 0) { /* Command complete */
unsigned long read_frame = dev->mem_start + rx_head; void __iomem *read_frame = lp->base + rx_head;
ushort rfd_cmd = isa_readw(read_frame+2); ushort rfd_cmd = readw(read_frame+2);
ushort next_rx_frame = isa_readw(read_frame+4); ushort next_rx_frame = readw(read_frame+4);
ushort data_buffer_addr = isa_readw(read_frame+6); ushort data_buffer_addr = readw(read_frame+6);
unsigned long data_frame = dev->mem_start + data_buffer_addr; void __iomem *data_frame = lp->base + data_buffer_addr;
ushort pkt_len = isa_readw(data_frame); ushort pkt_len = readw(data_frame);
if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22 if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
|| (pkt_len & 0xC000) != 0xC000) { || (pkt_len & 0xC000) != 0xC000) {
...@@ -865,7 +876,7 @@ static void el16_rx(struct net_device *dev) ...@@ -865,7 +876,7 @@ static void el16_rx(struct net_device *dev)
skb->dev = dev; skb->dev = dev;
/* 'skb->data' points to the start of sk_buff data area. */ /* 'skb->data' points to the start of sk_buff data area. */
isa_memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len); memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len);
skb->protocol=eth_type_trans(skb,dev); skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb); netif_rx(skb);
...@@ -875,10 +886,10 @@ static void el16_rx(struct net_device *dev) ...@@ -875,10 +886,10 @@ static void el16_rx(struct net_device *dev)
} }
/* Clear the status word and set End-of-List on the rx frame. */ /* Clear the status word and set End-of-List on the rx frame. */
isa_writew(0,read_frame); writew(0,read_frame);
isa_writew(0xC000,read_frame+2); writew(0xC000,read_frame+2);
/* Clear the end-of-list on the prev. RFD. */ /* Clear the end-of-list on the prev. RFD. */
isa_writew(0x0000,dev->mem_start + rx_tail + 2); writew(0x0000,lp->base + rx_tail + 2);
rx_tail = rx_head; rx_tail = rx_head;
rx_head = next_rx_frame; rx_head = next_rx_frame;
...@@ -935,6 +946,7 @@ cleanup_module(void) ...@@ -935,6 +946,7 @@ cleanup_module(void)
struct net_device *dev = dev_3c507; struct net_device *dev = dev_3c507;
unregister_netdev(dev); unregister_netdev(dev);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
iounmap(((struct net_local *)netdev_priv(dev))->base);
release_region(dev->base_addr, EL16_IO_EXTENT); release_region(dev->base_addr, EL16_IO_EXTENT);
free_netdev(dev); free_netdev(dev);
} }
......
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