Commit dee12d4f authored by David S. Miller's avatar David S. Miller

[SPARC]: Fix build breakage.

- Update for PCI config space access api changes
- Handle new do_fork args
- Delete SET/CLEAR TID handling from copy_thread
- Update arch/sparc64/defconfig
parent 117efdbb
...@@ -193,39 +193,34 @@ static void pci_do_settimeofday(struct timeval *tv); ...@@ -193,39 +193,34 @@ static void pci_do_settimeofday(struct timeval *tv);
#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3)) #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value); static int pcic_read_config(struct pci_bus *bus, unsigned int devfn,
static int pcic_write_config_dword(struct pci_dev *dev, int where, u32 value); int where, int size, u32 *value)
static int pcic_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
unsigned int v;
pcic_read_config_dword(dev, where&~3, &v);
*value = 0xff & (v >> (8*(where & 3)));
return PCIBIOS_SUCCESSFUL;
}
static int pcic_read_config_word(struct pci_dev *dev, int where, u16 *value)
{ {
unsigned int v; unsigned int v;
if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER; unsigned char busnum = bus->number;
struct linux_pcic *pcic;
unsigned long flags;
/* unsigned char where; */
pcic_read_config_dword(dev, where&~3, &v); switch (size) {
*value = 0xffff & (v >> (8*(where & 3))); case 1:
return PCIBIOS_SUCCESSFUL; pcic_read_config(bus, devfn, where&~3, 4, &v);
} *value = 0xff & (v >> (8*(where & 3)));
return PCIBIOS_SUCCESSFUL;
break;
static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value) case 2:
{ if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
unsigned char bus = dev->bus->number;
unsigned char device_fn = dev->devfn;
/* unsigned char where; */
struct linux_pcic *pcic; pcic_read_config(bus, devfn, where&~3, 4, &v);
unsigned long flags; *value = 0xffff & (v >> (8*(where & 3)));
return PCIBIOS_SUCCESSFUL;
break;
}
/* size == 4, i.e. dword */
if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER; if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
if (bus != 0) return PCIBIOS_DEVICE_NOT_FOUND; if (busnum != 0) return PCIBIOS_DEVICE_NOT_FOUND;
pcic = &pcic0; pcic = &pcic0;
save_and_cli(flags); save_and_cli(flags);
...@@ -233,7 +228,7 @@ static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value) ...@@ -233,7 +228,7 @@ static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value)
pcic_speculative = 1; pcic_speculative = 1;
pcic_trapped = 0; pcic_trapped = 0;
#endif #endif
writel(CONFIG_CMD(bus,device_fn,where), pcic->pcic_config_space_addr); writel(CONFIG_CMD(busnum,devfn,where), pcic->pcic_config_space_addr);
#if 0 /* does not fail here */ #if 0 /* does not fail here */
nop(); nop();
if (pcic_trapped) { if (pcic_trapped) {
...@@ -257,52 +252,46 @@ static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value) ...@@ -257,52 +252,46 @@ static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value)
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int pcic_write_config_byte(struct pci_dev *dev, int where, u8 value) static int pcic_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value)
{ {
unsigned int v; unsigned int v;
unsigned char busnum = bus->number;
pcic_read_config_dword(dev, where&~3, &v);
v = (v & ~(0xff << (8*(where&3)))) |
((0xff&(unsigned)value) << (8*(where&3)));
return pcic_write_config_dword(dev, where&~3, v);
}
static int pcic_write_config_word(struct pci_dev *dev, int where, u16 value)
{
unsigned int v;
if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
pcic_read_config_dword(dev, where&~3, &v);
v = (v & ~(0xffff << (8*(where&3)))) |
((0xffff&(unsigned)value) << (8*(where&3)));
return pcic_write_config_dword(dev, where&~3, v);
}
static int pcic_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
unsigned char bus = dev->bus->number;
unsigned char devfn = dev->devfn;
struct linux_pcic *pcic; struct linux_pcic *pcic;
unsigned long flags; unsigned long flags;
switch (size) {
case 1:
pcic_read_config(bus, devfn, where&~3, 4, &v);
v = (v & ~(0xff << (8*(where&3)))) |
((0xff&(unsigned)value) << (8*(where&3)));
return pcic_write_config(bus, devfn, where&~3, 4, v);
break;
case 2:
if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
pcic_read_config(bus, devfn, where&~3, 4, &v);
v = (v & ~(0xffff << (8*(where&3)))) |
((0xffff&(unsigned)value) << (8*(where&3)));
return pcic_write_config(bus, devfn, where&~3, 4, v);
break;
}
/* size == 4, i.e. dword */
if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER; if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
if (bus != 0) return PCIBIOS_DEVICE_NOT_FOUND; if (busnum != 0) return PCIBIOS_DEVICE_NOT_FOUND;
pcic = &pcic0; pcic = &pcic0;
save_and_cli(flags); save_and_cli(flags);
writel(CONFIG_CMD(bus,devfn,where), pcic->pcic_config_space_addr); writel(CONFIG_CMD(busnum,devfn,where), pcic->pcic_config_space_addr);
writel(value, pcic->pcic_config_space_data + (where&4)); writel(value, pcic->pcic_config_space_data + (where&4));
restore_flags(flags); restore_flags(flags);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static struct pci_ops pcic_ops = { static struct pci_ops pcic_ops = {
pcic_read_config_byte, .read = pcic_read_config,
pcic_read_config_word, .write = pcic_write_config,
pcic_read_config_dword,
pcic_write_config_byte,
pcic_write_config_word,
pcic_write_config_dword,
}; };
/* /*
......
...@@ -459,15 +459,16 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, ...@@ -459,15 +459,16 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
struct pt_regs *regs, struct pt_regs *regs,
unsigned long stack_size) unsigned long stack_size)
{ {
unsigned long tid_ptr = 0;
struct task_struct *p; struct task_struct *p;
/* XXX This was spelled in DaveM's will and testament. Why? */ clone_flags &= ~CLONE_IDLETASK;
if (clone_flags & CLONE_IDLETASK) {
printk(KERN_DEBUG "Userland clone with CLONE_IDLETASK\n"); if (clone_flags & (CLONE_SETTID | CLONE_CLEARTID))
clone_flags &= ~CLONE_IDLETASK; tid_ptr = regs->u_regs[UREG_G2];
}
p = do_fork(clone_flags, stack_start, regs, stack_size); p = do_fork(clone_flags, stack_start,
regs, stack_size, (int *) tid_ptr);
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
......
...@@ -388,6 +388,15 @@ CONFIG_ARPD=y ...@@ -388,6 +388,15 @@ CONFIG_ARPD=y
CONFIG_INET_ECN=y CONFIG_INET_ECN=y
# CONFIG_SYN_COOKIES is not set # CONFIG_SYN_COOKIES is not set
CONFIG_IPV6=m CONFIG_IPV6=m
#
# SCTP Configuration (EXPERIMENTAL)
#
CONFIG_IPV6_SCTP__=m
CONFIG_IP_SCTP=m
# CONFIG_SCTP_ADLER32 is not set
# CONFIG_SCTP_DBG_MSG is not set
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_ATM is not set # CONFIG_ATM is not set
CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q=m
CONFIG_LLC=m CONFIG_LLC=m
...@@ -613,9 +622,6 @@ CONFIG_SOUND_GAMEPORT=y ...@@ -613,9 +622,6 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_GAMEPORT_CS461x is not set # CONFIG_GAMEPORT_CS461x is not set
CONFIG_SERIO=y CONFIG_SERIO=y
CONFIG_SERIO_I8042=y CONFIG_SERIO_I8042=y
CONFIG_I8042_REG_BASE=60
CONFIG_I8042_KBD_IRQ=1
CONFIG_I8042_AUX_IRQ=12
# CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_SERPORT is not set
# CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PARKBD is not set
......
...@@ -669,10 +669,10 @@ static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg) ...@@ -669,10 +669,10 @@ static int bond_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
static __inline__ void *alloc_user_space(long len) static __inline__ void *alloc_user_space(long len)
{ {
struct pt_regs *regs = current->thread.kregs; struct pt_regs *regs = current_thread_info()->kregs;
unsigned long usp = regs->u_regs[UREG_I6]; unsigned long usp = regs->u_regs[UREG_I6];
if (!(current->thread.flags & SPARC_FLAG_32BIT)) if (!(test_thread_flag(TIF_32BIT)))
usp += STACK_BIAS; usp += STACK_BIAS;
return (void *) (usp - len); return (void *) (usp - len);
......
...@@ -107,119 +107,66 @@ static int psycho_out_of_range(struct pci_pbm_info *pbm, ...@@ -107,119 +107,66 @@ static int psycho_out_of_range(struct pci_pbm_info *pbm,
/* PSYCHO PCI configuration space accessors. */ /* PSYCHO PCI configuration space accessors. */
static int psycho_read_byte(struct pci_dev *dev, int where, u8 *value) static int psycho_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 *value)
{ {
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
unsigned char bus = dev->bus->number; unsigned char bus = bus_dev->number;
unsigned int devfn = dev->devfn;
u8 *addr;
*value = 0xff;
addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (psycho_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
pci_config_read8(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int psycho_read_word(struct pci_dev *dev, int where, u16 *value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u16 *addr;
*value = 0xffff;
addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (psycho_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
if (where & 0x01) {
printk("pcibios_read_config_word: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_read16(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int psycho_read_dword(struct pci_dev *dev, int where, u32 *value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u32 *addr; u32 *addr;
u16 tmp16;
*value = 0xffffffff; u8 tmp8;
addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr) switch (size) {
return PCIBIOS_SUCCESSFUL; case 1:
*value = 0xff;
if (psycho_out_of_range(pbm, bus, devfn)) break;
return PCIBIOS_SUCCESSFUL; case 2:
*value = 0xffff;
if (where & 0x03) { break;
printk("pcibios_read_config_dword: misaligned reg [%x]\n", case 4:
where); *value = 0xffffffff;
return PCIBIOS_SUCCESSFUL; break;
} }
pci_config_read32(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int psycho_write_byte(struct pci_dev *dev, int where, u8 value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u8 *addr;
addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (psycho_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
pci_config_write8(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int psycho_write_word(struct pci_dev *dev, int where, u16 value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u16 *addr;
addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr) if (!addr)
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
if (psycho_out_of_range(pbm, bus, devfn)) if (psycho_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
switch (size) {
if (where & 0x01) { case 1:
printk("pcibios_write_config_word: misaligned reg [%x]\n", pci_config_read8((u8 *)addr, &tmp8);
where); *value = (u32) tmp8;
return PCIBIOS_SUCCESSFUL; break;
case 2:
if (where & 0x01) {
printk("pci_read_config_word: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_read16((u16 *)addr, &tmp16);
*value = (u32) tmp16;
break;
case 4:
if (where & 0x03) {
printk("pci_read_config_dword: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_read32(addr, value);
break;
} }
pci_config_write16(addr, value);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int psycho_write_dword(struct pci_dev *dev, int where, u32 value) static int psycho_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 value)
{ {
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
unsigned char bus = dev->bus->number; unsigned char bus = bus_dev->number;
unsigned int devfn = dev->devfn;
u32 *addr; u32 *addr;
addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where); addr = psycho_pci_config_mkaddr(pbm, bus, devfn, where);
...@@ -229,22 +176,34 @@ static int psycho_write_dword(struct pci_dev *dev, int where, u32 value) ...@@ -229,22 +176,34 @@ static int psycho_write_dword(struct pci_dev *dev, int where, u32 value)
if (psycho_out_of_range(pbm, bus, devfn)) if (psycho_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
if (where & 0x03) { switch (size) {
printk("pcibios_write_config_dword: misaligned reg [%x]\n", case 1:
where); pci_config_write8((u8 *)addr, value);
return PCIBIOS_SUCCESSFUL; break;
case 2:
if (where & 0x01) {
printk("pci_write_config_word: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_write16((u16 *)addr, value);
break;
case 4:
if (where & 0x03) {
printk("pci_write_config_dword: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_write32(addr, value);
} }
pci_config_write32(addr, value);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static struct pci_ops psycho_ops = { static struct pci_ops psycho_ops = {
psycho_read_byte, .read = psycho_read_pci_cfg,
psycho_read_word, .write = psycho_write_pci_cfg,
psycho_read_dword,
psycho_write_byte,
psycho_write_word,
psycho_write_dword
}; };
/* PSYCHO interrupt mapping support. */ /* PSYCHO interrupt mapping support. */
......
...@@ -258,56 +258,27 @@ static int __sabre_out_of_range(struct pci_pbm_info *pbm, ...@@ -258,56 +258,27 @@ static int __sabre_out_of_range(struct pci_pbm_info *pbm,
PCI_SLOT(devfn) > 8)); PCI_SLOT(devfn) > 8));
} }
static int __sabre_read_byte(struct pci_dev *dev, int where, u8 *value) static int __sabre_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 *value)
{ {
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
unsigned char bus = dev->bus->number; unsigned char bus = bus_dev->number;
unsigned int devfn = dev->devfn; u32 *addr;
u8 *addr; u16 tmp16;
u8 tmp8;
*value = 0xff;
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (__sabre_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
pci_config_read8(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int __sabre_read_word(struct pci_dev *dev, int where, u16 *value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u16 *addr;
*value = 0xffff;
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (__sabre_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
if (where & 0x01) { switch (size) {
printk("pcibios_read_config_word: misaligned reg [%x]\n", case 1:
where); *value = 0xff;
return PCIBIOS_SUCCESSFUL; break;
case 2:
*value = 0xffff;
break;
case 4:
*value = 0xffffffff;
break;
} }
pci_config_read16(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int __sabre_read_dword(struct pci_dev *dev, int where, u32 *value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u32 *addr;
*value = 0xffffffff;
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where); addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr) if (!addr)
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
...@@ -315,86 +286,110 @@ static int __sabre_read_dword(struct pci_dev *dev, int where, u32 *value) ...@@ -315,86 +286,110 @@ static int __sabre_read_dword(struct pci_dev *dev, int where, u32 *value)
if (__sabre_out_of_range(pbm, bus, devfn)) if (__sabre_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
if (where & 0x03) { switch (size) {
printk("pcibios_read_config_dword: misaligned reg [%x]\n", case 1:
where); pci_config_read8((u8 *) addr, &tmp8);
return PCIBIOS_SUCCESSFUL; *value = tmp8;
} break;
pci_config_read32(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int sabre_read_byte(struct pci_dev *dev, int where, u8 *value) case 2:
{ if (where & 0x01) {
if (dev->bus->number) printk("pci_read_config_word: misaligned reg [%x]\n",
return __sabre_read_byte(dev, where, value); where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_read16((u16 *) addr, &tmp16);
*value = tmp16;
break;
if (sabre_out_of_range(dev->devfn)) { case 4:
*value = 0xff; if (where & 0x03) {
return PCIBIOS_SUCCESSFUL; printk("pci_read_config_dword: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_read32(addr, value);
break;
} }
if (where < 8) { return PCIBIOS_SUCCESSFUL;
u16 tmp;
__sabre_read_word(dev, where & ~1, &tmp);
if (where & 1)
*value = tmp >> 8;
else
*value = tmp & 0xff;
return PCIBIOS_SUCCESSFUL;
} else
return __sabre_read_byte(dev, where, value);
} }
static int sabre_read_word(struct pci_dev *dev, int where, u16 *value) static int sabre_read_pci_cfg(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *value)
{ {
if (dev->bus->number) if (bus->number)
return __sabre_read_word(dev, where, value); return __sabre_read_pci_cfg(bus, devfn, where, size, value);
if (sabre_out_of_range(dev->devfn)) { if (sabre_out_of_range(devfn)) {
*value = 0xffff; switch (size) {
case 1:
*value = 0xff;
break;
case 2:
*value = 0xffff;
break;
case 4:
*value = 0xffffffff;
break;
}
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
if (where < 8) switch (size) {
return __sabre_read_word(dev, where, value); case 1:
else { if (where < 8) {
u8 tmp; u32 tmp32;
u16 tmp16;
__sabre_read_byte(dev, where, &tmp);
*value = tmp; __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32);
__sabre_read_byte(dev, where + 1, &tmp); tmp16 = (u16) tmp32;
*value |= tmp << 8; if (where & 1)
return PCIBIOS_SUCCESSFUL; *value = tmp16 >> 8;
} else
} *value = tmp16 & 0xff;
} else
return __sabre_read_pci_cfg(bus, devfn, where, 1, value);
break;
static int sabre_read_dword(struct pci_dev *dev, int where, u32 *value) case 2:
{ if (where < 8)
u16 tmp; return __sabre_read_pci_cfg(bus, devfn, where, 2, value);
else {
u32 tmp32;
u8 tmp8;
__sabre_read_pci_cfg(bus, devfn, where, 1, &tmp32);
tmp8 = (u8) tmp32;
*value = tmp8;
__sabre_read_pci_cfg(bus, devfn, where + 1, 1, &tmp32);
tmp8 = (u8) tmp32;
*value |= tmp8 << 8;
}
break;
if (dev->bus->number) case 4: {
return __sabre_read_dword(dev, where, value); u32 tmp32;
u16 tmp16;
if (sabre_out_of_range(dev->devfn)) { sabre_read_pci_cfg(bus, devfn, where, 2, &tmp32);
*value = 0xffffffff; tmp16 = (u16) tmp32;
return PCIBIOS_SUCCESSFUL; *value = tmp16;
sabre_read_pci_cfg(bus, devfn, where + 2, 2, &tmp32);
tmp16 = (u16) tmp32;
*value |= tmp16 << 16;
break;
}
} }
sabre_read_word(dev, where, &tmp);
*value = tmp;
sabre_read_word(dev, where + 2, &tmp);
*value |= tmp << 16;
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int __sabre_write_byte(struct pci_dev *dev, int where, u8 value) static int __sabre_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 value)
{ {
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
unsigned char bus = dev->bus->number; unsigned char bus = bus_dev->number;
unsigned int devfn = dev->devfn; u32 *addr;
u8 *addr;
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where); addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr) if (!addr)
...@@ -402,117 +397,82 @@ static int __sabre_write_byte(struct pci_dev *dev, int where, u8 value) ...@@ -402,117 +397,82 @@ static int __sabre_write_byte(struct pci_dev *dev, int where, u8 value)
if (__sabre_out_of_range(pbm, bus, devfn)) if (__sabre_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
pci_config_write8(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int __sabre_write_word(struct pci_dev *dev, int where, u16 value) switch (size) {
{ case 1:
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; pci_config_write8((u8 *) addr, value);
unsigned char bus = dev->bus->number; break;
unsigned int devfn = dev->devfn;
u16 *addr;
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (__sabre_out_of_range(pbm, bus, devfn)) case 2:
return PCIBIOS_SUCCESSFUL; if (where & 0x01) {
printk("pci_write_config_word: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_write16((u16 *) addr, value);
break;
if (where & 0x01) { case 4:
printk("pcibios_write_config_word: misaligned reg [%x]\n", if (where & 0x03) {
where); printk("pci_write_config_dword: misaligned reg [%x]\n",
return PCIBIOS_SUCCESSFUL; where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_write32(addr, value);
break;
} }
pci_config_write16(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int __sabre_write_dword(struct pci_dev *dev, int where, u32 value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u32 *addr;
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (__sabre_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
if (where & 0x03) {
printk("pcibios_write_config_dword: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_write32(addr, value);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int sabre_write_byte(struct pci_dev *dev, int where, u8 value) static int sabre_write_pci_cfg(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value)
{ {
if (dev->bus->number) if (bus->number)
return __sabre_write_byte(dev, where, value); return __sabre_write_pci_cfg(bus, devfn, where, size, value);
if (sabre_out_of_range(dev->devfn)) if (sabre_out_of_range(devfn))
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
if (where < 8) { switch (size) {
u16 tmp; case 1:
if (where < 8) {
__sabre_read_word(dev, where & ~1, &tmp); u32 tmp32;
if (where & 1) { u16 tmp16;
value &= 0x00ff;
value |= tmp << 8; __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32);
} else { tmp16 = (u16) tmp32;
value &= 0xff00; if (where & 1) {
value |= tmp; value &= 0x00ff;
value |= tmp16 << 8;
} else {
value &= 0xff00;
value |= tmp16;
}
tmp32 = (u32) tmp16;
return __sabre_write_pci_cfg(bus, devfn, where & ~1, 2, tmp32);
} else
return __sabre_write_pci_cfg(bus, devfn, where, 1, value);
break;
case 2:
if (where < 8)
return __sabre_write_pci_cfg(bus, devfn, where, 2, value);
else {
__sabre_write_pci_cfg(bus, devfn, where, 1, value & 0xff);
__sabre_write_pci_cfg(bus, devfn, where + 1, 1, value >> 8);
} }
return __sabre_write_word(dev, where & ~1, tmp); break;
} else case 4:
return __sabre_write_byte(dev, where, value); sabre_write_pci_cfg(bus, devfn, where, 2, value & 0xffff);
} sabre_write_pci_cfg(bus, devfn, where + 2, 2, value >> 16);
break;
static int sabre_write_word(struct pci_dev *dev, int where, u16 value)
{
if (dev->bus->number)
return __sabre_write_word(dev, where, value);
if (sabre_out_of_range(dev->devfn))
return PCIBIOS_SUCCESSFUL;
if (where < 8)
return __sabre_write_word(dev, where, value);
else {
__sabre_write_byte(dev, where, value & 0xff);
__sabre_write_byte(dev, where + 1, value >> 8);
return PCIBIOS_SUCCESSFUL;
} }
}
static int sabre_write_dword(struct pci_dev *dev, int where, u32 value)
{
if (dev->bus->number)
return __sabre_write_dword(dev, where, value);
if (sabre_out_of_range(dev->devfn))
return PCIBIOS_SUCCESSFUL;
sabre_write_word(dev, where, value & 0xffff);
sabre_write_word(dev, where + 2, value >> 16);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static struct pci_ops sabre_ops = { static struct pci_ops sabre_ops = {
sabre_read_byte, .read = sabre_read_pci_cfg,
sabre_read_word, .write = sabre_write_pci_cfg,
sabre_read_dword,
sabre_write_byte,
sabre_write_word,
sabre_write_dword
}; };
static unsigned long sabre_pcislot_imap_offset(unsigned long ino) static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
...@@ -1112,31 +1072,41 @@ static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre ...@@ -1112,31 +1072,41 @@ static void __init apb_init(struct pci_controller_info *p, struct pci_bus *sabre
if (pdev->vendor == PCI_VENDOR_ID_SUN && if (pdev->vendor == PCI_VENDOR_ID_SUN &&
pdev->device == PCI_DEVICE_ID_SUN_SIMBA) { pdev->device == PCI_DEVICE_ID_SUN_SIMBA) {
u16 word; u32 word32;
u16 word16;
sabre_read_word(pdev, PCI_COMMAND, &word); sabre_read_pci_cfg(pdev->bus, pdev->devfn,
word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND, 2, &word32);
word16 = (u16) word32;
word16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
PCI_COMMAND_IO; PCI_COMMAND_IO;
sabre_write_word(pdev, PCI_COMMAND, word); word32 = (u32) word16;
sabre_write_pci_cfg(pdev->bus, pdev->devfn,
PCI_COMMAND, 2, word32);
/* Status register bits are "write 1 to clear". */ /* Status register bits are "write 1 to clear". */
sabre_write_word(pdev, PCI_STATUS, 0xffff); sabre_write_pci_cfg(pdev->bus, pdev->devfn,
sabre_write_word(pdev, PCI_SEC_STATUS, 0xffff); PCI_STATUS, 2, 0xffff);
sabre_write_pci_cfg(pdev->bus, pdev->devfn,
PCI_SEC_STATUS, 2, 0xffff);
/* Use a primary/seconday latency timer value /* Use a primary/seconday latency timer value
* of 64. * of 64.
*/ */
sabre_write_byte(pdev, PCI_LATENCY_TIMER, 64); sabre_write_pci_cfg(pdev->bus, pdev->devfn,
sabre_write_byte(pdev, PCI_SEC_LATENCY_TIMER, 64); PCI_LATENCY_TIMER, 1, 64);
sabre_write_pci_cfg(pdev->bus, pdev->devfn,
PCI_SEC_LATENCY_TIMER, 1, 64);
/* Enable reporting/forwarding of master aborts, /* Enable reporting/forwarding of master aborts,
* parity, and SERR. * parity, and SERR.
*/ */
sabre_write_byte(pdev, PCI_BRIDGE_CONTROL, sabre_write_pci_cfg(pdev->bus, pdev->devfn,
(PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CONTROL, 1,
PCI_BRIDGE_CTL_SERR | (PCI_BRIDGE_CTL_PARITY |
PCI_BRIDGE_CTL_MASTER_ABORT)); PCI_BRIDGE_CTL_SERR |
PCI_BRIDGE_CTL_MASTER_ABORT));
} }
} }
} }
......
...@@ -124,119 +124,66 @@ static int schizo_out_of_range(struct pci_pbm_info *pbm, ...@@ -124,119 +124,66 @@ static int schizo_out_of_range(struct pci_pbm_info *pbm,
/* SCHIZO PCI configuration space accessors. */ /* SCHIZO PCI configuration space accessors. */
static int schizo_read_byte(struct pci_dev *dev, int where, u8 *value) static int schizo_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 *value)
{ {
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
unsigned char bus = dev->bus->number; unsigned char bus = bus_dev->number;
unsigned int devfn = dev->devfn;
u8 *addr;
*value = 0xff;
addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (schizo_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
pci_config_read8(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int schizo_read_word(struct pci_dev *dev, int where, u16 *value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u16 *addr;
*value = 0xffff;
addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (schizo_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
if (where & 0x01) {
printk("pcibios_read_config_word: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_read16(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int schizo_read_dword(struct pci_dev *dev, int where, u32 *value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u32 *addr; u32 *addr;
u16 tmp16;
*value = 0xffffffff; u8 tmp8;
addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr) switch (size) {
return PCIBIOS_SUCCESSFUL; case 1:
*value = 0xff;
if (schizo_out_of_range(pbm, bus, devfn)) break;
return PCIBIOS_SUCCESSFUL; case 2:
*value = 0xffff;
if (where & 0x03) { break;
printk("pcibios_read_config_dword: misaligned reg [%x]\n", case 4:
where); *value = 0xffffffff;
return PCIBIOS_SUCCESSFUL; break;
} }
pci_config_read32(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int schizo_write_byte(struct pci_dev *dev, int where, u8 value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u8 *addr;
addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (schizo_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
pci_config_write8(addr, value);
return PCIBIOS_SUCCESSFUL;
}
static int schizo_write_word(struct pci_dev *dev, int where, u16 value)
{
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number];
unsigned char bus = dev->bus->number;
unsigned int devfn = dev->devfn;
u16 *addr;
addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr) if (!addr)
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
if (schizo_out_of_range(pbm, bus, devfn)) if (schizo_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
switch (size) {
if (where & 0x01) { case 1:
printk("pcibios_write_config_word: misaligned reg [%x]\n", pci_config_read8((u8 *)addr, &tmp8);
where); *value = tmp8;
return PCIBIOS_SUCCESSFUL; break;
case 2:
if (where & 0x01) {
printk("pci_read_config_word: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_read16((u16 *)addr, &tmp16);
*value = tmp16;
break;
case 4:
if (where & 0x03) {
printk("pci_read_config_dword: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_read32(addr, value);
break;
} }
pci_config_write16(addr, value);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static int schizo_write_dword(struct pci_dev *dev, int where, u32 value) static int schizo_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
int where, int size, u32 value)
{ {
struct pci_pbm_info *pbm = pci_bus2pbm[dev->bus->number]; struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
unsigned char bus = dev->bus->number; unsigned char bus = bus_dev->number;
unsigned int devfn = dev->devfn;
u32 *addr; u32 *addr;
addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where); addr = schizo_pci_config_mkaddr(pbm, bus, devfn, where);
...@@ -246,22 +193,34 @@ static int schizo_write_dword(struct pci_dev *dev, int where, u32 value) ...@@ -246,22 +193,34 @@ static int schizo_write_dword(struct pci_dev *dev, int where, u32 value)
if (schizo_out_of_range(pbm, bus, devfn)) if (schizo_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
if (where & 0x03) { switch (size) {
printk("pcibios_write_config_dword: misaligned reg [%x]\n", case 1:
where); pci_config_write8((u8 *)addr, value);
return PCIBIOS_SUCCESSFUL; break;
case 2:
if (where & 0x01) {
printk("pci_write_config_word: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_write16((u16 *)addr, value);
break;
case 4:
if (where & 0x03) {
printk("pci_write_config_dword: misaligned reg [%x]\n",
where);
return PCIBIOS_SUCCESSFUL;
}
pci_config_write32(addr, value);
} }
pci_config_write32(addr, value);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
static struct pci_ops schizo_ops = { static struct pci_ops schizo_ops = {
schizo_read_byte, .read = schizo_read_pci_cfg,
schizo_read_word, .write = schizo_write_pci_cfg,
schizo_read_dword,
schizo_write_byte,
schizo_write_word,
schizo_write_dword
}; };
/* SCHIZO interrupt mapping support. Unlike Psycho, for this controller the /* SCHIZO interrupt mapping support. Unlike Psycho, for this controller the
......
...@@ -568,8 +568,19 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags, ...@@ -568,8 +568,19 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
struct pt_regs *regs, struct pt_regs *regs,
unsigned long stack_size) unsigned long stack_size)
{ {
struct task_struct *p = do_fork(clone_flags, stack_start, struct task_struct *p;
regs, stack_size); unsigned long tid_ptr = 0;
clone_flags &= ~CLONE_IDLETASK;
if (clone_flags & (CLONE_SETTID | CLONE_CLEARTID)) {
tid_ptr = regs->u_regs[UREG_G2];
if (test_thread_flag(TIF_32BIT))
tid_ptr &= 0xffffffff;
}
p = do_fork(clone_flags, stack_start,
regs, stack_size, (int *) tid_ptr);
return IS_ERR(p) ? PTR_ERR(p) : p->pid; return IS_ERR(p) ? PTR_ERR(p) : p->pid;
} }
...@@ -649,19 +660,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -649,19 +660,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
/* Set the second return value for the parent. */ /* Set the second return value for the parent. */
regs->u_regs[UREG_I1] = 0; regs->u_regs[UREG_I1] = 0;
if (!(clone_flags & (CLONE_SETTID | CLONE_CLEARTID)))
return 0;
if (t->flags & _TIF_32BIT)
t->kregs->u_regs[UREG_G2] &= 0xffffffff;
if (clone_flags & CLONE_SETTID)
if (put_user(p->pid, (int *)t->kregs->u_regs[UREG_G2]))
return -EFAULT;
if (clone_flags & CLONE_CLEARTID)
p->user_tid = (int *) t->kregs->u_regs[UREG_G2];
return 0; return 0;
} }
......
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