diff options
| author | David S. Miller <davem@nuts.ninka.net> | 2002-08-31 08:36:40 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2002-08-31 08:36:40 -0700 |
| commit | dee12d4fa83188ff2374884b1115dc2397c95eaa (patch) | |
| tree | 126c7b2ec12ab9fbfd8e3352bc663f0da633ee81 | |
| parent | 117efdbb3ed0f2b56fc7df7b4224770419255dc1 (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.c | 105 | ||||
| -rw-r--r-- | arch/sparc/kernel/process.c | 13 | ||||
| -rw-r--r-- | arch/sparc64/defconfig | 12 | ||||
| -rw-r--r-- | arch/sparc64/kernel/ioctl32.c | 4 | ||||
| -rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 177 | ||||
| -rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 394 | ||||
| -rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 177 | ||||
| -rw-r--r-- | arch/sparc64/kernel/process.c | 28 |
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; } |
