Commit 083eb98a authored by Linus Torvalds's avatar Linus Torvalds

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

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents b4d59dc8 2c92ae9a
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include <linux/security.h> #include <linux/security.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/ipc.h> #include <asm/ipc.h>
...@@ -2527,6 +2528,78 @@ asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int use ...@@ -2527,6 +2528,78 @@ asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int use
extern asmlinkage int sys_setsockopt(int fd, int level, int optname, extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
char *optval, int optlen); char *optval, int optlen);
static int do_netfilter_replace(int fd, int level, int optname,
char *optval, int optlen)
{
struct ipt_replace32 {
char name[IPT_TABLE_MAXNAMELEN];
__u32 valid_hooks;
__u32 num_entries;
__u32 size;
__u32 hook_entry[NF_IP_NUMHOOKS];
__u32 underflow[NF_IP_NUMHOOKS];
__u32 num_counters;
__u32 counters;
struct ipt_entry entries[0];
} *repl32 = (struct ipt_replace32 *)optval;
struct ipt_replace *krepl;
struct ipt_counters *counters32;
__u32 origsize;
unsigned int kreplsize, kcountersize;
mm_segment_t old_fs;
int ret;
if (optlen < sizeof(repl32))
return -EINVAL;
if (copy_from_user(&origsize,
&repl32->size,
sizeof(origsize)))
return -EFAULT;
kreplsize = sizeof(*krepl) + origsize;
kcountersize = krepl->num_counters * sizeof(struct ipt_counters);
/* Hack: Causes ipchains to give correct error msg --RR */
if (optlen != kreplsize)
return -ENOPROTOOPT;
krepl = (struct ipt_replace *)kmalloc(kreplsize, GFP_KERNEL);
if (krepl == NULL)
return -ENOMEM;
if (copy_from_user(krepl, optval, kreplsize)) {
kfree(krepl);
return -EFAULT;
}
counters32 = (struct ipt_counters *)AA(
((struct ipt_replace32 *)krepl)->counters);
kcountersize = krepl->num_counters * sizeof(struct ipt_counters);
krepl->counters = (struct ipt_counters *)kmalloc(
kcountersize, GFP_KERNEL);
if (krepl->counters == NULL) {
kfree(krepl);
return -ENOMEM;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_setsockopt(fd, level, optname,
(char *)krepl, kreplsize);
set_fs(old_fs);
if (ret == 0 &&
copy_to_user(counters32, krepl->counters, kcountersize))
ret = -EFAULT;
kfree(krepl->counters);
kfree(krepl);
return ret;
}
static int do_set_attach_filter(int fd, int level, int optname, static int do_set_attach_filter(int fd, int level, int optname,
char *optval, int optlen) char *optval, int optlen)
{ {
...@@ -2620,6 +2693,9 @@ static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int ...@@ -2620,6 +2693,9 @@ static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int
asmlinkage int sys32_setsockopt(int fd, int level, int optname, asmlinkage int sys32_setsockopt(int fd, int level, int optname,
char *optval, int optlen) char *optval, int optlen)
{ {
if (optname == IPT_SO_SET_REPLACE)
return do_netfilter_replace(fd, level, optname,
optval, optlen);
if (optname == SO_ATTACH_FILTER) if (optname == SO_ATTACH_FILTER)
return do_set_attach_filter(fd, level, optname, return do_set_attach_filter(fd, level, optname,
optval, optlen); optval, optlen);
......
...@@ -47,8 +47,6 @@ struct uart_sunsab_port { ...@@ -47,8 +47,6 @@ struct uart_sunsab_port {
struct uart_port port; /* Generic UART port */ struct uart_port port; /* Generic UART port */
union sab82532_async_regs *regs; /* Chip registers */ union sab82532_async_regs *regs; /* Chip registers */
unsigned long irqflags; /* IRQ state flags */ unsigned long irqflags; /* IRQ state flags */
int xmit_fifo_size; /* TX fifo size */
int recv_fifo_size; /* RX fifo size */
int dsr; /* Current DSR state */ int dsr; /* Current DSR state */
unsigned int cec_timeout; /* Chip poll timeout... */ unsigned int cec_timeout; /* Chip poll timeout... */
unsigned int tec_timeout; /* likewise */ unsigned int tec_timeout; /* likewise */
...@@ -57,8 +55,6 @@ struct uart_sunsab_port { ...@@ -57,8 +55,6 @@ struct uart_sunsab_port {
unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */ unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */
unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */ unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */
int type; /* SAB82532 version */ int type; /* SAB82532 version */
int sab_line; /* Internal numbering */
unsigned int irq; /* Device interrupt */
}; };
/* /*
...@@ -76,6 +72,9 @@ static char *sab82532_version[16] = { ...@@ -76,6 +72,9 @@ static char *sab82532_version[16] = {
#define SAB82532_MAX_TEC_TIMEOUT 200000 /* 1 character time (at 50 baud) */ #define SAB82532_MAX_TEC_TIMEOUT 200000 /* 1 character time (at 50 baud) */
#define SAB82532_MAX_CEC_TIMEOUT 50000 /* 2.5 TX CLKs (at 50 baud) */ #define SAB82532_MAX_CEC_TIMEOUT 50000 /* 2.5 TX CLKs (at 50 baud) */
#define SAB82532_RECV_FIFO_SIZE 32 /* Standard async fifo sizes */
#define SAB82532_XMIT_FIFO_SIZE 32
static __inline__ void sunsab_tec_wait(struct uart_sunsab_port *up) static __inline__ void sunsab_tec_wait(struct uart_sunsab_port *up)
{ {
int timeout = up->tec_timeout; int timeout = up->tec_timeout;
...@@ -105,12 +104,12 @@ static void receive_chars(struct uart_sunsab_port *up, ...@@ -105,12 +104,12 @@ static void receive_chars(struct uart_sunsab_port *up,
/* Read number of BYTES (Character + Status) available. */ /* Read number of BYTES (Character + Status) available. */
if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
count = up->recv_fifo_size; count = SAB82532_RECV_FIFO_SIZE;
free_fifo++; free_fifo++;
} }
if (stat->sreg.isr0 & SAB82532_ISR0_TCD) { if (stat->sreg.isr0 & SAB82532_ISR0_TCD) {
count = readb(&up->regs->r.rbcl) & (up->recv_fifo_size - 1); count = readb(&up->regs->r.rbcl) & (SAB82532_RECV_FIFO_SIZE - 1);
free_fifo++; free_fifo++;
} }
...@@ -246,13 +245,13 @@ static void transmit_chars(struct uart_sunsab_port *up, ...@@ -246,13 +245,13 @@ static void transmit_chars(struct uart_sunsab_port *up,
return; return;
} }
up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS); up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR);
writeb(up->interrupt_mask1, &up->regs->w.imr1); writeb(up->interrupt_mask1, &up->regs->w.imr1);
clear_bit(SAB82532_ALLS, &up->irqflags); clear_bit(SAB82532_ALLS, &up->irqflags);
/* Stuff 32 bytes into Transmit FIFO. */ /* Stuff 32 bytes into Transmit FIFO. */
clear_bit(SAB82532_XPR, &up->irqflags); clear_bit(SAB82532_XPR, &up->irqflags);
for (i = 0; i < up->xmit_fifo_size; i++) { for (i = 0; i < up->port.fifosize; i++) {
writeb(xmit->buf[xmit->tail], writeb(xmit->buf[xmit->tail],
&up->regs->w.xfifo[i]); &up->regs->w.xfifo[i]);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
...@@ -422,15 +421,16 @@ static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start) ...@@ -422,15 +421,16 @@ static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start)
struct circ_buf *xmit = &up->port.info->xmit; struct circ_buf *xmit = &up->port.info->xmit;
int i; int i;
up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR);
writeb(up->interrupt_mask1, &up->regs->w.imr1);
if (!test_bit(SAB82532_XPR, &up->irqflags)) if (!test_bit(SAB82532_XPR, &up->irqflags))
return; return;
up->interrupt_mask1 &= ~SAB82532_IMR1_XPR;
writeb(up->interrupt_mask1, &up->regs->w.imr1);
clear_bit(SAB82532_ALLS, &up->irqflags); clear_bit(SAB82532_ALLS, &up->irqflags);
clear_bit(SAB82532_XPR, &up->irqflags); clear_bit(SAB82532_XPR, &up->irqflags);
for (i = 0; i < up->xmit_fifo_size; i++) { for (i = 0; i < up->port.fifosize; i++) {
writeb(xmit->buf[xmit->tail], writeb(xmit->buf[xmit->tail],
&up->regs->w.xfifo[i]); &up->regs->w.xfifo[i]);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
...@@ -533,33 +533,7 @@ static int sunsab_startup(struct uart_port *port) ...@@ -533,33 +533,7 @@ static int sunsab_startup(struct uart_port *port)
writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4); writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4);
writeb(SAB82532_MODE_RTS | SAB82532_MODE_FCTS | writeb(SAB82532_MODE_RTS | SAB82532_MODE_FCTS |
SAB82532_MODE_RAC, &up->regs->w.mode); SAB82532_MODE_RAC, &up->regs->w.mode);
writeb(SAB82532_RFC_DPS | SAB82532_RFC_RFDF, &up->regs->w.rfc); writeb(SAB82532_RFC_DPS|SAB82532_RFC_RFTH_32, &up->regs->w.rfc);
switch (up->recv_fifo_size) {
case 1:
tmp = readb(&up->regs->w.rfc);
tmp |= SAB82532_RFC_RFTH_1;
writeb(tmp, &up->regs->w.rfc);
break;
case 4:
tmp = readb(&up->regs->w.rfc);
tmp |= SAB82532_RFC_RFTH_4;
writeb(tmp, &up->regs->w.rfc);
break;
case 16:
tmp = readb(&up->regs->w.rfc);
tmp |= SAB82532_RFC_RFTH_16;
writeb(tmp, &up->regs->w.rfc);
break;
default:
up->recv_fifo_size = 32;
/* fall through */
case 32:
tmp = readb(&up->regs->w.rfc);
tmp |= SAB82532_RFC_RFTH_32;
writeb(tmp, &up->regs->w.rfc);
break;
};
tmp = readb(&up->regs->rw.ccr0); tmp = readb(&up->regs->rw.ccr0);
tmp |= SAB82532_CCR0_PU; /* power-up */ tmp |= SAB82532_CCR0_PU; /* power-up */
...@@ -796,7 +770,11 @@ static void sunsab_change_speed(struct uart_port *port, unsigned int cflag, ...@@ -796,7 +770,11 @@ static void sunsab_change_speed(struct uart_port *port, unsigned int cflag,
static const char *sunsab_type(struct uart_port *port) static const char *sunsab_type(struct uart_port *port)
{ {
return "SunSAB"; struct uart_sunsab_port *up = (void *)port;
static char buf[36];
sprintf(buf, "SAB82532 %s", sab82532_version[up->type]);
return buf;
} }
static void sunsab_release_port(struct uart_port *port) static void sunsab_release_port(struct uart_port *port)
...@@ -1011,22 +989,25 @@ static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg ...@@ -1011,22 +989,25 @@ static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg
unsigned long regs, offset; unsigned long regs, offset;
int i; int i;
/* Note: ports are located in reverse order */
regs = edev->resource[0].start; regs = edev->resource[0].start;
offset = sizeof(union sab82532_async_regs); offset = sizeof(union sab82532_async_regs);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
up = &sunsab_ports[(*instance_p * 2) + i]; up = &sunsab_ports[(*instance_p * 2) + 1 - i];
memset(up, 0, sizeof(*up)); memset(up, 0, sizeof(*up));
up->regs = ioremap(regs + offset, sizeof(union sab82532_async_regs)); up->regs = ioremap(regs + offset, sizeof(union sab82532_async_regs));
up->irq = edev->irqs[0]; up->port.irq = edev->irqs[0];
up->sab_line = 1 - i; up->port.fifosize = SAB82532_XMIT_FIFO_SIZE;
up->xmit_fifo_size = 32; up->port.mapbase = (unsigned long)up->regs;
up->recv_fifo_size = 32; up->port.iotype = SERIAL_IO_MEM;
writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc); writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc);
offset -= sizeof(union sab82532_async_regs); offset -= sizeof(union sab82532_async_regs);
} }
(*instance_p)++;
} }
static int __init probe_for_sabs(void) static int __init probe_for_sabs(void)
...@@ -1066,7 +1047,7 @@ static void __init sunsab_init_hw(void) ...@@ -1066,7 +1047,7 @@ static void __init sunsab_init_hw(void)
up->type = readb(&up->regs->r.vstr) & 0x0f; up->type = readb(&up->regs->r.vstr) & 0x0f;
writeb(~((1 << 1) | (1 << 2) | (1 << 4)), &up->regs->w.pcr); writeb(~((1 << 1) | (1 << 2) | (1 << 4)), &up->regs->w.pcr);
writeb(0xff, &up->regs->w.pim); writeb(0xff, &up->regs->w.pim);
if (up->sab_line == 0) { if (up->port.line == 0) {
up->pvr_dsr_bit = (1 << 0); up->pvr_dsr_bit = (1 << 0);
up->pvr_dtr_bit = (1 << 1); up->pvr_dtr_bit = (1 << 1);
} else { } else {
...@@ -1082,19 +1063,14 @@ static void __init sunsab_init_hw(void) ...@@ -1082,19 +1063,14 @@ static void __init sunsab_init_hw(void)
up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
if (!(up->sab_line & 0x01)) { if (!(up->port.line & 0x01)) {
if (request_irq(up->irq, sunsab_interrupt, SA_SHIRQ, if (request_irq(up->port.irq, sunsab_interrupt,
"serial(sab82532)", up)) { SA_SHIRQ, "serial(sab82532)", up)) {
printk("sunsab%d: can't get IRQ %x\n", printk("sunsab%d: can't get IRQ %x\n",
i, up->irq); i, up->port.irq);
continue; continue;
} }
} }
printk(KERN_INFO
"sunsab%d at 0x%lx (irq = %s) is a SAB82532 %s\n",
i, (unsigned long)up->regs,
__irq_itoa(up->irq), sab82532_version[up->type]);
} }
} }
...@@ -1109,8 +1085,6 @@ static int __init sunsab_init(void) ...@@ -1109,8 +1085,6 @@ static int __init sunsab_init(void)
sunsab_init_hw(); sunsab_init_hw();
sunsab_reg.minor = sunserial_current_minor; sunsab_reg.minor = sunserial_current_minor;
sunserial_current_minor += num_channels;
sunsab_reg.nr = num_channels; sunsab_reg.nr = num_channels;
sunsab_reg.cons = &sunsab_console; sunsab_reg.cons = &sunsab_console;
...@@ -1121,8 +1095,8 @@ static int __init sunsab_init(void) ...@@ -1121,8 +1095,8 @@ static int __init sunsab_init(void)
for (i = 0; i < num_channels; i++) { for (i = 0; i < num_channels; i++) {
struct uart_sunsab_port *up = &sunsab_ports[i]; struct uart_sunsab_port *up = &sunsab_ports[i];
if (!(up->sab_line & 0x01)) if (!(up->port.line & 0x01))
free_irq(up->irq, up); free_irq(up->port.irq, up);
iounmap(up->regs); iounmap(up->regs);
} }
kfree(sunsab_ports); kfree(sunsab_ports);
...@@ -1131,6 +1105,8 @@ static int __init sunsab_init(void) ...@@ -1131,6 +1105,8 @@ static int __init sunsab_init(void)
return ret; return ret;
} }
sunserial_current_minor += num_channels;
for (i = 0; i < num_channels; i++) { for (i = 0; i < num_channels; i++) {
struct uart_sunsab_port *up = &sunsab_ports[i]; struct uart_sunsab_port *up = &sunsab_ports[i];
...@@ -1151,11 +1127,12 @@ static void __exit sunsab_exit(void) ...@@ -1151,11 +1127,12 @@ static void __exit sunsab_exit(void)
uart_remove_one_port(&sunsab_reg, &up->port); uart_remove_one_port(&sunsab_reg, &up->port);
if (!(up->sab_line & 0x01)) if (!(up->port.line & 0x01))
free_irq(up->irq, up); free_irq(up->port.irq, up);
iounmap(up->regs); iounmap(up->regs);
} }
sunserial_current_minor -= num_channels;
uart_unregister_driver(&sunsab_reg); uart_unregister_driver(&sunsab_reg);
kfree(sunsab_ports); kfree(sunsab_ports);
......
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