summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.ninka.net>2002-08-31 08:36:40 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2002-08-31 08:36:40 -0700
commitdee12d4fa83188ff2374884b1115dc2397c95eaa (patch)
tree126c7b2ec12ab9fbfd8e3352bc663f0da633ee81
parent117efdbb3ed0f2b56fc7df7b4224770419255dc1 (diff)
[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
-rw-r--r--arch/sparc/kernel/pcic.c105
-rw-r--r--arch/sparc/kernel/process.c13
-rw-r--r--arch/sparc64/defconfig12
-rw-r--r--arch/sparc64/kernel/ioctl32.c4
-rw-r--r--arch/sparc64/kernel/pci_psycho.c177
-rw-r--r--arch/sparc64/kernel/pci_sabre.c394
-rw-r--r--arch/sparc64/kernel/pci_schizo.c177
-rw-r--r--arch/sparc64/kernel/process.c28
8 files changed, 396 insertions, 514 deletions
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index a3c03f632cef..b542a666eca1 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -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))
-static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value);
-static int pcic_write_config_dword(struct pci_dev *dev, int where, 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)
+static int pcic_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *value)
{
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);
- *value = 0xffff & (v >> (8*(where & 3)));
- return PCIBIOS_SUCCESSFUL;
-}
+ switch (size) {
+ case 1:
+ 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)
-{
- unsigned char bus = dev->bus->number;
- unsigned char device_fn = dev->devfn;
- /* unsigned char where; */
+ case 2:
+ if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
- struct linux_pcic *pcic;
- unsigned long flags;
+ pcic_read_config(bus, devfn, where&~3, 4, &v);
+ *value = 0xffff & (v >> (8*(where & 3)));
+ return PCIBIOS_SUCCESSFUL;
+ break;
+ }
+ /* size == 4, i.e. dword */
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;
save_and_cli(flags);
@@ -233,7 +228,7 @@ static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value)
pcic_speculative = 1;
pcic_trapped = 0;
#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 */
nop();
if (pcic_trapped) {
@@ -257,52 +252,46 @@ static int pcic_read_config_dword(struct pci_dev *dev, int where, u32 *value)
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;
-
- 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;
+ unsigned char busnum = bus->number;
struct linux_pcic *pcic;
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 (bus != 0) return PCIBIOS_DEVICE_NOT_FOUND;
+ if (busnum != 0) return PCIBIOS_DEVICE_NOT_FOUND;
pcic = &pcic0;
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));
restore_flags(flags);
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops pcic_ops = {
- pcic_read_config_byte,
- pcic_read_config_word,
- pcic_read_config_dword,
- pcic_write_config_byte,
- pcic_write_config_word,
- pcic_write_config_dword,
+ .read = pcic_read_config,
+ .write = pcic_write_config,
};
/*
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 73572be45b3e..04908ae9ada3 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -459,15 +459,16 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
struct pt_regs *regs,
unsigned long stack_size)
{
+ unsigned long tid_ptr = 0;
struct task_struct *p;
- /* XXX This was spelled in DaveM's will and testament. Why? */
- if (clone_flags & CLONE_IDLETASK) {
- printk(KERN_DEBUG "Userland clone with CLONE_IDLETASK\n");
- clone_flags &= ~CLONE_IDLETASK;
- }
+ clone_flags &= ~CLONE_IDLETASK;
+
+ if (clone_flags & (CLONE_SETTID | CLONE_CLEARTID))
+ 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;
}
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 7880b94f71cd..d310bc37154f 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -388,6 +388,15 @@ CONFIG_ARPD=y
CONFIG_INET_ECN=y
# CONFIG_SYN_COOKIES is not set
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_VLAN_8021Q=m
CONFIG_LLC=m
@@ -613,9 +622,6 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_GAMEPORT_CS461x is not set
CONFIG_SERIO=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_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 8157a2b486fc..8804e569e7ea 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -669,10 +669,10 @@ out:
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];
- if (!(current->thread.flags & SPARC_FLAG_32BIT))
+ if (!(test_thread_flag(TIF_32BIT)))
usp += STACK_BIAS;
return (void *) (usp - len);
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 3d2230a82351..09991c28860f 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -107,119 +107,66 @@ static int psycho_out_of_range(struct pci_pbm_info *pbm,
/* 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];
- unsigned char bus = dev->bus->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;
+ struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ unsigned char bus = bus_dev->number;
u32 *addr;
-
- *value = 0xffffffff;
- 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 & 0x03) {
- printk("pcibios_read_config_dword: misaligned reg [%x]\n",
- where);
- return PCIBIOS_SUCCESSFUL;
+ u16 tmp16;
+ u8 tmp8;
+
+ switch (size) {
+ case 1:
+ *value = 0xff;
+ break;
+ case 2:
+ *value = 0xffff;
+ break;
+ case 4:
+ *value = 0xffffffff;
+ 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);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (psycho_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
-
- if (where & 0x01) {
- printk("pcibios_write_config_word: misaligned reg [%x]\n",
- where);
- return PCIBIOS_SUCCESSFUL;
+ switch (size) {
+ case 1:
+ pci_config_read8((u8 *)addr, &tmp8);
+ *value = (u32) tmp8;
+ 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;
}
-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];
- unsigned char bus = dev->bus->number;
- unsigned int devfn = dev->devfn;
+ struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ unsigned char bus = bus_dev->number;
u32 *addr;
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)
if (psycho_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;
+ switch (size) {
+ case 1:
+ pci_config_write8((u8 *)addr, value);
+ 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;
}
static struct pci_ops psycho_ops = {
- psycho_read_byte,
- psycho_read_word,
- psycho_read_dword,
- psycho_write_byte,
- psycho_write_word,
- psycho_write_dword
+ .read = psycho_read_pci_cfg,
+ .write = psycho_write_pci_cfg,
};
/* PSYCHO interrupt mapping support. */
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 0de9131492b9..b6621c5f0f50 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -258,56 +258,27 @@ static int __sabre_out_of_range(struct pci_pbm_info *pbm,
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];
- unsigned char bus = dev->bus->number;
- unsigned int devfn = dev->devfn;
- u8 *addr;
-
- *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;
+ struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ unsigned char bus = bus_dev->number;
+ u32 *addr;
+ u16 tmp16;
+ u8 tmp8;
- if (where & 0x01) {
- printk("pcibios_read_config_word: misaligned reg [%x]\n",
- where);
- return PCIBIOS_SUCCESSFUL;
+ switch (size) {
+ case 1:
+ *value = 0xff;
+ 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);
if (!addr)
return PCIBIOS_SUCCESSFUL;
@@ -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))
return PCIBIOS_SUCCESSFUL;
- if (where & 0x03) {
- printk("pcibios_read_config_dword: misaligned reg [%x]\n",
- where);
- return PCIBIOS_SUCCESSFUL;
- }
- pci_config_read32(addr, value);
- return PCIBIOS_SUCCESSFUL;
-}
+ switch (size) {
+ case 1:
+ pci_config_read8((u8 *) addr, &tmp8);
+ *value = tmp8;
+ break;
-static int sabre_read_byte(struct pci_dev *dev, int where, u8 *value)
-{
- if (dev->bus->number)
- return __sabre_read_byte(dev, where, value);
+ 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;
- if (sabre_out_of_range(dev->devfn)) {
- *value = 0xff;
- return PCIBIOS_SUCCESSFUL;
+ case 4:
+ if (where & 0x03) {
+ printk("pci_read_config_dword: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ pci_config_read32(addr, value);
+ break;
}
- if (where < 8) {
- 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);
+ return PCIBIOS_SUCCESSFUL;
}
-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)
- return __sabre_read_word(dev, where, value);
+ if (bus->number)
+ return __sabre_read_pci_cfg(bus, devfn, where, size, value);
- if (sabre_out_of_range(dev->devfn)) {
- *value = 0xffff;
+ if (sabre_out_of_range(devfn)) {
+ switch (size) {
+ case 1:
+ *value = 0xff;
+ break;
+ case 2:
+ *value = 0xffff;
+ break;
+ case 4:
+ *value = 0xffffffff;
+ break;
+ }
return PCIBIOS_SUCCESSFUL;
}
- if (where < 8)
- return __sabre_read_word(dev, where, value);
- else {
- u8 tmp;
-
- __sabre_read_byte(dev, where, &tmp);
- *value = tmp;
- __sabre_read_byte(dev, where + 1, &tmp);
- *value |= tmp << 8;
- return PCIBIOS_SUCCESSFUL;
- }
-}
+ switch (size) {
+ case 1:
+ if (where < 8) {
+ u32 tmp32;
+ u16 tmp16;
+
+ __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32);
+ tmp16 = (u16) tmp32;
+ if (where & 1)
+ *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)
-{
- u16 tmp;
+ case 2:
+ if (where < 8)
+ 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)
- return __sabre_read_dword(dev, where, value);
+ case 4: {
+ u32 tmp32;
+ u16 tmp16;
- if (sabre_out_of_range(dev->devfn)) {
- *value = 0xffffffff;
- return PCIBIOS_SUCCESSFUL;
+ sabre_read_pci_cfg(bus, devfn, where, 2, &tmp32);
+ tmp16 = (u16) tmp32;
+ *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;
}
-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];
- unsigned char bus = dev->bus->number;
- unsigned int devfn = dev->devfn;
- u8 *addr;
+ struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ unsigned char bus = bus_dev->number;
+ u32 *addr;
addr = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
if (!addr)
@@ -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))
return PCIBIOS_SUCCESSFUL;
- pci_config_write8(addr, value);
- return PCIBIOS_SUCCESSFUL;
-}
-static int __sabre_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 = sabre_pci_config_mkaddr(pbm, bus, devfn, where);
- if (!addr)
- return PCIBIOS_SUCCESSFUL;
+ switch (size) {
+ case 1:
+ pci_config_write8((u8 *) addr, value);
+ break;
- if (__sabre_out_of_range(pbm, bus, devfn))
- return PCIBIOS_SUCCESSFUL;
+ 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;
- if (where & 0x01) {
- printk("pcibios_write_config_word: misaligned reg [%x]\n",
- where);
- return PCIBIOS_SUCCESSFUL;
+ case 4:
+ if (where & 0x03) {
+ printk("pci_write_config_dword: misaligned reg [%x]\n",
+ 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;
}
-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)
- return __sabre_write_byte(dev, where, value);
+ if (bus->number)
+ 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;
- if (where < 8) {
- u16 tmp;
-
- __sabre_read_word(dev, where & ~1, &tmp);
- if (where & 1) {
- value &= 0x00ff;
- value |= tmp << 8;
- } else {
- value &= 0xff00;
- value |= tmp;
+ switch (size) {
+ case 1:
+ if (where < 8) {
+ u32 tmp32;
+ u16 tmp16;
+
+ __sabre_read_pci_cfg(bus, devfn, where & ~1, 2, &tmp32);
+ tmp16 = (u16) tmp32;
+ if (where & 1) {
+ 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);
- } else
- return __sabre_write_byte(dev, where, value);
-}
-
-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;
+ break;
+ case 4:
+ 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_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;
}
static struct pci_ops sabre_ops = {
- sabre_read_byte,
- sabre_read_word,
- sabre_read_dword,
- sabre_write_byte,
- sabre_write_word,
- sabre_write_dword
+ .read = sabre_read_pci_cfg,
+ .write = sabre_write_pci_cfg,
};
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
if (pdev->vendor == PCI_VENDOR_ID_SUN &&
pdev->device == PCI_DEVICE_ID_SUN_SIMBA) {
- u16 word;
+ u32 word32;
+ u16 word16;
- sabre_read_word(pdev, PCI_COMMAND, &word);
- word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
+ sabre_read_pci_cfg(pdev->bus, pdev->devfn,
+ PCI_COMMAND, 2, &word32);
+ word16 = (u16) word32;
+ word16 |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY |
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". */
- sabre_write_word(pdev, PCI_STATUS, 0xffff);
- sabre_write_word(pdev, PCI_SEC_STATUS, 0xffff);
+ sabre_write_pci_cfg(pdev->bus, pdev->devfn,
+ PCI_STATUS, 2, 0xffff);
+ sabre_write_pci_cfg(pdev->bus, pdev->devfn,
+ PCI_SEC_STATUS, 2, 0xffff);
/* Use a primary/seconday latency timer value
* of 64.
*/
- sabre_write_byte(pdev, PCI_LATENCY_TIMER, 64);
- sabre_write_byte(pdev, PCI_SEC_LATENCY_TIMER, 64);
+ sabre_write_pci_cfg(pdev->bus, pdev->devfn,
+ 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,
* parity, and SERR.
*/
- sabre_write_byte(pdev, PCI_BRIDGE_CONTROL,
- (PCI_BRIDGE_CTL_PARITY |
- PCI_BRIDGE_CTL_SERR |
- PCI_BRIDGE_CTL_MASTER_ABORT));
+ sabre_write_pci_cfg(pdev->bus, pdev->devfn,
+ PCI_BRIDGE_CONTROL, 1,
+ (PCI_BRIDGE_CTL_PARITY |
+ PCI_BRIDGE_CTL_SERR |
+ PCI_BRIDGE_CTL_MASTER_ABORT));
}
}
}
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index 48a81bf41462..72dff03c69ff 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -124,119 +124,66 @@ static int schizo_out_of_range(struct pci_pbm_info *pbm,
/* 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];
- unsigned char bus = dev->bus->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;
+ struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ unsigned char bus = bus_dev->number;
u32 *addr;
-
- *value = 0xffffffff;
- 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 & 0x03) {
- printk("pcibios_read_config_dword: misaligned reg [%x]\n",
- where);
- return PCIBIOS_SUCCESSFUL;
+ u16 tmp16;
+ u8 tmp8;
+
+ switch (size) {
+ case 1:
+ *value = 0xff;
+ break;
+ case 2:
+ *value = 0xffff;
+ break;
+ case 4:
+ *value = 0xffffffff;
+ 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);
if (!addr)
return PCIBIOS_SUCCESSFUL;
if (schizo_out_of_range(pbm, bus, devfn))
return PCIBIOS_SUCCESSFUL;
-
- if (where & 0x01) {
- printk("pcibios_write_config_word: misaligned reg [%x]\n",
- where);
- return PCIBIOS_SUCCESSFUL;
+ switch (size) {
+ case 1:
+ pci_config_read8((u8 *)addr, &tmp8);
+ *value = tmp8;
+ 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;
}
-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];
- unsigned char bus = dev->bus->number;
- unsigned int devfn = dev->devfn;
+ struct pci_pbm_info *pbm = pci_bus2pbm[bus_dev->number];
+ unsigned char bus = bus_dev->number;
u32 *addr;
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)
if (schizo_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;
+ switch (size) {
+ case 1:
+ pci_config_write8((u8 *)addr, value);
+ 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;
}
static struct pci_ops schizo_ops = {
- schizo_read_byte,
- schizo_read_word,
- schizo_read_dword,
- schizo_write_byte,
- schizo_write_word,
- schizo_write_dword
+ .read = schizo_read_pci_cfg,
+ .write = schizo_write_pci_cfg,
};
/* SCHIZO interrupt mapping support. Unlike Psycho, for this controller the
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 54e9dcb930e7..ab54ef260099 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -568,8 +568,19 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
struct pt_regs *regs,
unsigned long stack_size)
{
- struct task_struct *p = do_fork(clone_flags, stack_start,
- regs, stack_size);
+ struct task_struct *p;
+ 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;
}
@@ -649,19 +660,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
/* Set the second return value for the parent. */
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;
}