Commit 81c0cfcc authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

[PATCH] PA-RISC updates for 2.5.59

 - conversion of remaining drivers to generic device model
 - more of sfr's compat stuff
 - eliminate some bogus syscalls
 - update for MUX driver
 - beginnings of new module code
 - tell the keyboard driver about CONFIG_PARISC
parent 00492e8c
......@@ -33,10 +33,10 @@ FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align
OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
cflags-y := -D__linux__ -pipe -fno-strength-reduce
cflags-y := -pipe
# These should be on for older toolchains or SOM toolchains that don't
# enable them by default.
# These flags should be implied by an hppa-linux configuration, but they
# are not in gcc 3.2.
cflags-y += -mno-space-regs -mfast-indirect-calls
# No fixed-point multiply
......
......@@ -243,7 +243,7 @@ int show_interrupts(struct seq_file *p, void *v)
for (i = 0; i <= MAX_CPU_IRQ; i++) {
struct irqaction *action = &region->action[i];
unsigned int irq_no = IRQ_FROM_REGION(regnr) + i;
int j=0;
int j = 0;
if (!action->handler)
continue;
......@@ -251,7 +251,7 @@ int show_interrupts(struct seq_file *p, void *v)
#ifdef CONFIG_SMP
for (; j < NR_CPUS; j++)
#endif
seq_printf(p, "%10u ", kstat_cpu(j).irqs[regnr][irq_no]);
seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq_no]);
seq_printf(p, " %14s",
region->data.name ? region->data.name : "N/A");
......@@ -388,7 +388,7 @@ void do_irq(struct irqaction *action, int irq, struct pt_regs * regs)
int cpu = smp_processor_id();
irq_enter();
++kstat_cpu(cpu).irqs[IRQ_REGION(irq)][IRQ_OFFSET(irq)];
++kstat_cpu(cpu).irqs[irq];
DBG_IRQ(irq, ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq)));
......
......@@ -13,6 +13,12 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(c) 2003 Randolph Chung <tausq@debian.org>
The best reference for this stuff is probably the Processor-
Specific ELF Supplement for PA-RISC:
http://ftp.parisc-linux.org/docs/elf-pa-hp.pdf
*/
#include <linux/moduleloader.h>
#include <linux/elf.h>
......@@ -21,19 +27,92 @@
#include <linux/string.h>
#include <linux/kernel.h>
#if 0
#if 1
#define DEBUGP printk
#else
#define DEBUGP(fmt...)
#endif
enum parisc_fsel {
e_fsel,
e_lsel,
e_rsel,
e_lrsel,
e_rrsel
#ifndef __LP64__
struct got_entry {
Elf32_Addr addr;
};
struct fdesc_entry {
Elf32_Addr gp;
Elf32_Addr addr;
};
struct stub_entry {
Elf32_Word insns[2]; /* each stub entry has two insns */
};
#else
struct got_entry {
Elf64_Addr addr;
};
struct fdesc_entry {
Elf64_Addr dummy[2];
Elf64_Addr gp;
Elf64_Addr addr;
};
struct stub_entry {
Elf64_Word insns[4]; /* each stub entry has four insns */
};
#endif
/* Field selection types defined by hppa */
#define rnd(x) (((x)+0x1000)&~0x1fff)
/* fsel: full 32 bits */
#define fsel(v,a) ((v)+(a))
/* lsel: select left 21 bits */
#define lsel(v,a) (((v)+(a))>>11)
/* rsel: select right 11 bits */
#define rsel(v,a) (((v)+(a))&0x7ff)
/* lrsel with rounding of addend to nearest 8k */
#define lrsel(v,a) (((v)+rnd(a))>>11)
/* rrsel with rounding of addend to nearest 8k */
#define rrsel(v,a) ((((v)+rnd(a))&0x7ff)+((a)-rnd(a)))
#define mask(x,sz) ((x) & ~((1<<(sz))-1))
/* The reassemble_* functions prepare an immediate value for
insertion into an opcode. pa-risc uses all sorts of weird bitfields
in the instruction to hold the value. */
static inline int reassemble_14(int as14)
{
return (((as14 & 0x1fff) << 1) |
((as14 & 0x2000) >> 13));
}
static inline int reassemble_17(int as17)
{
return (((as17 & 0x10000) >> 16) |
((as17 & 0x0f800) << 5) |
((as17 & 0x00400) >> 8) |
((as17 & 0x003ff) << 3));
}
static inline int reassemble_21(int as21)
{
return (((as21 & 0x100000) >> 20) |
((as21 & 0x0ffe00) >> 8) |
((as21 & 0x000180) << 7) |
((as21 & 0x00007c) << 14) |
((as21 & 0x000003) << 12));
}
static inline int reassemble_22(int as22)
{
return (((as22 & 0x200000) >> 21) |
((as22 & 0x1f0000) << 5) |
((as22 & 0x00f800) << 5) |
((as22 & 0x000400) >> 8) |
((as22 & 0x0003ff) << 3));
}
void *module_alloc(unsigned long size)
{
......@@ -42,6 +121,81 @@ void *module_alloc(unsigned long size)
return vmalloc(size);
}
#ifndef __LP64__
static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
{
return 0;
}
static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
{
return 0;
}
static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
{
unsigned long cnt = 0;
for (; n > 0; n--, rela++)
{
switch (ELF32_R_TYPE(rela->r_info)) {
case R_PARISC_PCREL17F:
case R_PARISC_PCREL22F:
cnt++;
}
}
return cnt;
}
#else
static inline unsigned long count_gots(const Elf_Rela *rela, unsigned long n)
{
unsigned long cnt = 0;
for (; n > 0; n--, rela++)
{
switch (ELF64_R_TYPE(rela->r_info)) {
case R_PARISC_LTOFF21L:
case R_PARISC_LTOFF14R:
case R_PARISC_PCREL22F:
cnt++;
}
}
return cnt;
}
static inline unsigned long count_fdescs(const Elf_Rela *rela, unsigned long n)
{
unsigned long cnt = 3; /* 3 for finalize */
for (; n > 0; n--, rela++)
{
switch (ELF64_R_TYPE(rela->r_info)) {
case R_PARISC_FPTR64:
cnt++;
}
}
return cnt;
}
static inline unsigned long count_stubs(const Elf_Rela *rela, unsigned long n)
{
unsigned long cnt = 0;
for (; n > 0; n--, rela++)
{
switch (ELF64_R_TYPE(rela->r_info)) {
case R_PARISC_PCREL22F:
cnt++;
}
}
return cnt;
}
#endif
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
......@@ -51,35 +205,145 @@ void module_free(struct module *mod, void *module_region)
table entries. */
}
/* We don't need anything special. */
long module_core_size(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
const char *secstrings,
struct module *module)
#define CONST
int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
CONST Elf_Shdr *sechdrs,
CONST char *secstrings,
struct module *me)
{
return module->core_size;
unsigned long gots = 0, fdescs = 0, stubs = 0;
unsigned int i;
for (i = 1; i < hdr->e_shnum; i++) {
const Elf_Rela *rels = (void *)hdr + sechdrs[i].sh_offset;
unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels);
if (sechdrs[i].sh_type != SHT_RELA)
continue;
/* some of these are not relevant for 32-bit/64-bit
* we leave them here to make the code common. the
* compiler will do its thing and optimize out the
* stuff we don't need
*/
gots += count_gots(rels, nrels);
fdescs += count_fdescs(rels, nrels);
stubs += count_stubs(rels, nrels);
}
/* align things a bit */
me->core_size = ALIGN(me->core_size, 16);
me->arch.got_offset = me->core_size;
me->core_size += gots * sizeof(struct got_entry);
me->core_size = ALIGN(me->core_size, 16);
me->arch.fdesc_offset = me->core_size;
me->core_size += stubs * sizeof(struct fdesc_entry);
me->core_size = ALIGN(me->core_size, 16);
me->arch.stub_offset = me->core_size;
me->core_size += stubs * sizeof(struct stub_entry);
return 0;
}
long module_init_size(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
const char *secstrings,
struct module *module)
static Elf_Addr get_got(struct module *me, unsigned long value, long addend)
{
return module->init_size;
unsigned int i;
struct got_entry *got;
value += addend;
BUG_ON(value == 0);
got = me->module_core + me->arch.got_offset;
for (i = 0; got[i].addr; i++)
if (got[i].addr == value)
return i * sizeof(struct got_entry);
got[i].addr = value;
return i * sizeof(struct got_entry);
}
int module_frob_arch_sections(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs,
char *secstrings,
struct module *mod)
static Elf_Addr get_fdesc(struct module *me, unsigned long value)
{
/* parisc should not need this ... */
printk(KERN_ERR "module %s: %s not yet implemented.\n",
mod->name, __FUNCTION__);
return 0;
struct fdesc_entry *fdesc = me->module_core + me->arch.fdesc_offset;
if (!value) {
printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
return 0;
}
/* Look for existing fdesc entry. */
while (fdesc->addr) {
if (fdesc->addr == value)
return (Elf_Addr)fdesc;
fdesc++;
}
/* Create new one */
fdesc->addr = value;
fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
return (Elf_Addr)fdesc;
}
static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
int millicode)
{
unsigned long i;
struct stub_entry *stub;
i = me->arch.stub_count++;
stub = me->module_core + me->arch.stub_offset +
i * sizeof(struct stub_entry);
#ifndef __LP64__
/* for 32-bit the stub looks like this:
* ldil L'XXX,%r1
* be,n R'XXX(%sr4,%r1)
*/
stub->insns[0] = 0x20200000; /* ldil L'XXX,%r1 */
stub->insns[1] = 0xe0202002; /* be,n R'XXX(%sr4,%r1) */
stub->insns[0] |= reassemble_21(lrsel(value, addend));
stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4);
#else
/* for 64-bit we have two kinds of stubs:
* for normal function calls:
* ldd 0(%dp),%dp
* ldd 10(%dp), %r1
* bve (%r1)
* ldd 18(%dp), %dp
*
* for millicode:
* ldil 0, %r1
* ldo 0(%r1), %r1
* ldd 10(%r1), %r1
* bve,n (%r1)
*/
if (!millicode)
{
stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */
stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */
stub->insns[2] = 0xe820d000; /* bve (%r1) */
stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */
stub->insns[0] |= reassemble_21(get_got(me, value, addend));
}
else
{
stub->insns[0] = 0x20200000; /* ldil 0,%r1 */
stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */
stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */
stub->insns[3] = 0xe820d002; /* bve,n (%r1) */
stub->insns[0] |= reassemble_21(lrsel(value, addend));
stub->insns[1] |= reassemble_14(rrsel(value, addend));
}
#endif
return (Elf_Addr)stub;
}
int apply_relocate(Elf_Shdr *sechdrs,
const char *strtab,
......@@ -104,7 +368,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym;
Elf32_Word *loc;
Elf32_Addr value;
Elf32_Addr val;
Elf32_Sword addend;
Elf32_Addr dot;
register unsigned long dp asm ("r27");
DEBUGP("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
......@@ -120,59 +387,81 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
me->name, strtab + sym->st_name);
return -ENOENT;
}
dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
value = sym->st_value + rel[i].r_addend;
val = sym->st_value;
addend = rel[i].r_addend;
DEBUGP("Symbol %s loc 0x%lx value 0x%lx: ",
#if 0
#define r(t) ELF32_R_TYPE(rel[i].r_info)==t ? #t :
DEBUGP("Symbol %s loc 0x%x val 0x%x addend 0x%x: %s\n",
strtab + sym->st_name,
(uint32_t)loc, value);
(uint32_t)loc, val, addend,
r(R_PARISC_PLABEL32)
r(R_PARISC_DIR32)
r(R_PARISC_DIR21L)
r(R_PARISC_DIR14R)
r(R_PARISC_SEGREL32)
r(R_PARISC_DPREL21L)
r(R_PARISC_DPREL14R)
r(R_PARISC_PCREL17F)
r(R_PARISC_PCREL22F)
"UNKNOWN");
#undef r
#endif
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_PARISC_PLABEL32:
/* 32-bit function address */
DEBUGP("R_PARISC_PLABEL32\n");
/* no function descriptors... */
*loc = fsel(val, addend);
break;
case R_PARISC_DIR32:
/* direct 32-bit ref */
DEBUGP("R_PARISC_DIR32\n");
*loc = fsel(val, addend);
break;
case R_PARISC_DIR21L:
/* left 21 bits of effective address */
DEBUGP("R_PARISC_DIR21L\n");
*loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend));
break;
case R_PARISC_DIR14R:
/* right 14 bits of effective address */
DEBUGP("R_PARISC_DIR14R\n");
*loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend));
break;
case R_PARISC_SEGREL32:
/* 32-bit segment relative address */
DEBUGP("R_PARISC_SEGREL32\n");
val -= (uint32_t)me->module_core;
*loc = fsel(val, addend);
break;
case R_PARISC_DPREL21L:
/* left 21 bit of relative address */
DEBUGP("R_PARISC_DPREL21L\n");
val -= dp;
*loc = mask(*loc, 21) | reassemble_21(lrsel(val, addend) - dp);
break;
case R_PARISC_DPREL14R:
/* right 14 bit of relative address */
DEBUGP("R_PARISC_DPREL14R\n");
val -= dp;
*loc = mask(*loc, 14) | reassemble_14(rrsel(val, addend) - dp);
break;
case R_PARISC_PCREL17F:
/* 17-bit PC relative address */
DEBUGP("R_PARISC_PCREL17F\n");
val = get_stub(me, val, addend, 0) - dot - 8;
*loc = (*loc&0x1f1ffd) | reassemble_17(val);
break;
case R_PARISC_PCREL22F:
/* 22-bit PC relative address */
DEBUGP("R_PARISC_PCREL22F\n");
/* 22-bit PC relative address; only defined for pa20 */
val = get_stub(me, val, addend, 0) - dot - 8;
*loc = (*loc&0x3ff1ffd) | reassemble_22(val);
break;
default:
printk(KERN_ERR "module %s: Unknown relocation: %Lu\n",
printk(KERN_ERR "module %s: Unknown relocation: %u\n",
me->name, ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return -ENOEXEC;
return 0;
}
#else
......@@ -186,7 +475,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf64_Sym *sym;
Elf64_Word *loc;
Elf64_Addr value;
Elf64_Addr val;
Elf64_Sxword addend;
Elf64_Addr dot;
DEBUGP("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
......@@ -202,38 +493,56 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
me->name, strtab + sym->st_name);
return -ENOENT;
}
dot = (sechdrs[relsec].sh_addr + rel->r_offset) & ~0x03;
value = sym->st_value + rel[i].r_addend;
val = sym->st_value;
addend = rel[i].r_addend;
DEBUGP("Symbol %s loc 0x%Lx value 0x%Lx: ",
#if 1
#define r(t) ELF64_R_TYPE(rel[i].r_info)==t ? #t :
DEBUGP("Symbol %s loc %p val 0x%Lx addend 0x%Lx: %s\n",
strtab + sym->st_name,
(uint64_t)loc, value);
loc, val, addend,
r(R_PARISC_LTOFF14R)
r(R_PARISC_LTOFF21L)
r(R_PARISC_PCREL22F)
r(R_PARISC_DIR64)
r(R_PARISC_SEGREL32)
r(R_PARISC_FPTR64)
"UNKNOWN");
#undef r
#endif
switch (ELF64_R_TYPE(rel[i].r_info)) {
case R_PARISC_LTOFF14R:
/* LT-relative; right 14 bits */
DEBUGP("R_PARISC_LTOFF14R\n");
break;
case R_PARISC_LTOFF21L:
/* LT-relative; left 21 bits */
DEBUGP("R_PARISC_LTOFF21L\n");
*loc = mask(*loc, 21) | reassemble_21(get_got(me, val, addend));
break;
case R_PARISC_LTOFF14R:
/* L(ltoff(val+addend)) */
/* LT-relative; right 14 bits */
*loc = mask(*loc, 14) | reassemble_14(get_got(me, val, addend));
break;
case R_PARISC_PCREL22F:
/* PC-relative; 22 bits */
DEBUGP("R_PARISC_PCREL22F\n");
if (strncmp(strtab + sym->st_name, "$$", 2) == 0)
val = get_stub(me, val, addend, 1) - dot - 8;
else
val = get_stub(me, val, addend, 0) - dot - 8;
*loc = (*loc&0x3ff1ffd) | reassemble_22(val);
break;
case R_PARISC_DIR64:
/* 64-bit effective address */
DEBUGP("R_PARISC_DIR64\n");
*loc = value;
*loc = fsel(val, addend);
break;
case R_PARISC_SEGREL32:
/* 32-bit segment relative address */
DEBUGP("R_PARISC_SEGREL32\n");
val -= (uint64_t)me->module_core;
*loc = fsel(val, addend);
break;
case R_PARISC_FPTR64:
/* 64-bit function address */
DEBUGP("R_PARISC_FPTR64\n");
*loc = get_fdesc(me, val+addend);
break;
default:
......@@ -242,7 +551,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
return -ENOEXEC;
}
}
return -ENOEXEC;
return 0;
}
#endif
......@@ -250,5 +559,14 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
#ifdef __LP64__
me->init = (void *)get_fdesc(me, (Elf_Addr)me->init);
#ifdef CONFIG_MODULE_UNLOAD
if (me->cleanup)
me->cleanup = (void *)get_fdesc(me, (Elf_Addr)me->cleanup);
if (me->destroy)
me->destroy = (void *)get_fdesc(me, (Elf_Addr)me->destroy);
#endif
#endif
return 0;
}
......@@ -31,10 +31,6 @@ EXPORT_SYMBOL(hppa_dma_ops);
EXPORT_SYMBOL(get_pci_node_path);
#endif
#ifdef CONFIG_IOMMU_CCIO
EXPORT_SYMBOL(ccio_get_fake);
#endif
#include <linux/sched.h>
#include <asm/irq.h>
EXPORT_SYMBOL(enable_irq);
......
......@@ -17,59 +17,6 @@ struct k_sigaction32 {
struct sigaction32 sa;
};
typedef unsigned int old_sigset_t32;
static int
put_old_sigset32(old_sigset_t32 *up, old_sigset_t *set)
{
old_sigset_t32 set32 = *set;
return put_user(set32, up);
}
static int
get_old_segset32(old_sigset_t32 *up, old_sigset_t *set)
{
old_sigset_t32 set32;
int r;
if ((r = get_user(set32, up)) == 0)
*set = set32;
return r;
}
long
sys32_sigpending(old_sigset_t32 *set)
{
extern long sys_sigpending(old_sigset_t *set);
old_sigset_t pending;
int ret;
KERNEL_SYSCALL(ret, sys_sigpending, &pending);
/* can't put_user an old_sigset_t -- it is too big */
if (put_old_sigset32(set, &pending))
return -EFAULT;
return ret;
}
int sys32_sigprocmask(int how, old_sigset_t32 *set,
old_sigset_t32 *oset)
{
extern int sys_sigprocmask(int how, old_sigset_t *set,
old_sigset_t *oset);
old_sigset_t s;
int ret;
if (set && get_old_segset32 (set, &s))
return -EFAULT;
KERNEL_SYSCALL(ret, sys_sigprocmask, how, set ? &s : NULL, oset ? &s : NULL);
if (!ret && oset && put_old_sigset32(oset, &s))
return -EFAULT;
return ret;
}
static inline void
sigset_32to64(sigset_t *s64, sigset_t32 *s32)
{
......
......@@ -314,74 +314,6 @@ asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23,
return -ENOSYS;
}
/* 32-bit user apps use struct statfs which uses 'long's */
struct statfs32 {
__s32 f_type;
__s32 f_bsize;
__s32 f_blocks;
__s32 f_bfree;
__s32 f_bavail;
__s32 f_files;
__s32 f_ffree;
__kernel_fsid_t f_fsid;
__s32 f_namelen;
__s32 f_spare[6];
};
/* convert statfs struct to statfs32 struct and copy result to user */
static unsigned long statfs32_to_user(struct statfs32 *ust32, struct statfs *st)
{
struct statfs32 st32;
#undef CP
#define CP(a) st32.a = st->a
CP(f_type);
CP(f_bsize);
CP(f_blocks);
CP(f_bfree);
CP(f_bavail);
CP(f_files);
CP(f_ffree);
CP(f_fsid);
CP(f_namelen);
return copy_to_user(ust32, &st32, sizeof st32);
}
/* The following statfs calls are copies of code from linux/fs/open.c and
* should be checked against those from time to time */
asmlinkage long sys32_statfs(const char * path, struct statfs32 * buf)
{
struct nameidata nd;
int error;
error = user_path_walk(path, &nd);
if (!error) {
struct statfs tmp;
error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
if (!error && statfs32_to_user(buf, &tmp))
error = -EFAULT;
path_release(&nd);
}
return error;
}
asmlinkage long sys32_fstatfs(unsigned int fd, struct statfs32 * buf)
{
struct file * file;
struct statfs tmp;
int error;
error = -EBADF;
file = fget(fd);
if (!file)
goto out;
error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
if (!error && statfs32_to_user(buf, &tmp))
error = -EFAULT;
fput(file);
out:
return error;
}
extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
......
......@@ -425,30 +425,27 @@ sys_call_table:
/* I don't like this */
ENTRY_UHOH(sgetmask)
ENTRY_UHOH(ssetmask)
ENTRY_SAME(setreuid) /* 70 */
ENTRY_SAME(setreuid) /* 70 */
ENTRY_SAME(setregid)
ENTRY_SAME(mincore)
ENTRY_DIFF(sigpending)
ENTRY_COMP(sigpending)
ENTRY_SAME(sethostname)
/* Following 3 have linux-common-code structs containing longs -( */
ENTRY_DIFF(setrlimit) /* 75 */
ENTRY_DIFF(setrlimit) /* 75 */
ENTRY_DIFF(getrlimit)
ENTRY_DIFF(getrusage)
/* struct timeval and timezone are maybe?? consistent wide and narrow */
ENTRY_DIFF(gettimeofday)
ENTRY_DIFF(settimeofday)
ENTRY_SAME(getgroups) /* 80 */
ENTRY_SAME(getgroups) /* 80 */
ENTRY_SAME(setgroups)
/* struct socketaddr... */
ENTRY_SAME(sendto)
ENTRY_SAME(symlink)
/* see stat comment */
ENTRY_COMP(newlstat)
ENTRY_SAME(readlink) /* 85 */
/* suspect we'll need some work for narrow shlibs on wide kernel */
/* NOTE this doesn't get used when I boot 32-bit userspace */
/* containing working shlib apps -- can this be nuked? */
ENTRY_UHOH(uselib)
ENTRY_SAME(readlink) /* 85 */
ENTRY_SAME(ni_syscall) /* was uselib */
ENTRY_SAME(swapon)
ENTRY_SAME(reboot)
ENTRY_SAME(mmap2)
......@@ -461,17 +458,15 @@ sys_call_table:
ENTRY_SAME(getpriority)
ENTRY_SAME(setpriority)
ENTRY_SAME(recv)
ENTRY_DIFF(statfs)
ENTRY_DIFF(fstatfs) /* 100 */
ENTRY_COMP(statfs)
ENTRY_COMP(fstatfs) /* 100 */
ENTRY_SAME(stat64)
/* don't think hppa glibc even provides an entry pt for this
* so disable for now */
ENTRY_UHOH(socketcall)
ENTRY_SAME(ni_syscall) /* was socketcall */
ENTRY_SAME(syslog)
/* even though manpage says struct timeval contains longs, ours has
* time_t and suseconds_t -- both of which are safe wide/narrow */
ENTRY_COMP(setitimer)
ENTRY_COMP(getitimer) /* 105 */
ENTRY_COMP(getitimer) /* 105 */
ENTRY_SAME(capget)
ENTRY_SAME(capset)
ENTRY_OURS(pread64)
......@@ -494,10 +489,10 @@ sys_call_table:
ENTRY_SAME(recvfrom)
/* struct timex contains longs */
ENTRY_DIFF(adjtimex)
ENTRY_SAME(mprotect) /* 125 */
ENTRY_SAME(mprotect) /* 125 */
/* old_sigset_t forced to 32 bits. Beware glibc sigset_t */
ENTRY_DIFF(sigprocmask)
ENTRY_SAME(ni_syscall) /* create_module */
ENTRY_COMP(sigprocmask)
ENTRY_SAME(ni_syscall) /* create_module */
ENTRY_SAME(init_module)
ENTRY_SAME(delete_module)
ENTRY_SAME(ni_syscall) /* 130: get_kernel_syms */
......@@ -547,13 +542,13 @@ sys_call_table:
ENTRY_COMP(nanosleep)
ENTRY_SAME(mremap)
ENTRY_SAME(setresuid)
ENTRY_SAME(getresuid) /* 165 */
ENTRY_SAME(getresuid) /* 165 */
ENTRY_DIFF(sigaltstack_wrapper)
ENTRY_SAME(ni_syscall) /* query_module */
ENTRY_SAME(poll)
/* structs contain pointers and an in_addr... */
ENTRY_DIFF(nfsservctl)
ENTRY_SAME(setresgid) /* 170 */
ENTRY_SAME(setresgid) /* 170 */
ENTRY_SAME(getresgid)
ENTRY_SAME(prctl)
/* signals need a careful review */
......@@ -594,15 +589,9 @@ sys_call_table:
ENTRY_OURS(ftruncate64) /* 200 */
ENTRY_SAME(getdents64)
ENTRY_DIFF(fcntl64)
#ifdef CONFIG_XFS_FS
ENTRY_SAME(attrctl)
ENTRY_SAME(acl_get)
ENTRY_SAME(acl_set) /* 205 */
#else
ENTRY_SAME(ni_syscall)
ENTRY_SAME(ni_syscall)
ENTRY_SAME(ni_syscall) /* 205 */
#endif
ENTRY_SAME(gettid)
ENTRY_SAME(readahead)
ENTRY_SAME(ni_syscall) /* tkill */
......
......@@ -123,7 +123,11 @@ void dump_stack(void)
}
static int kstack_depth_to_print = 48;
#ifndef __LP64__
static int kstack_depth_to_print = 64 * 4;
#else
static int kstack_depth_to_print = 128 * 4;
#endif
void show_stack(unsigned long *sp)
{
......
......@@ -918,7 +918,7 @@ static void kbd_bh(unsigned long dummy)
DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC)
static unsigned short x86_keycodes[256] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
......
......@@ -91,6 +91,7 @@
#include <asm/irq.h>
#include <asm/pdc.h>
#include <asm/cache.h>
#include <asm/parisc-device.h>
static char version[] __devinitdata =
"82596.c $Revision: 1.29 $\n";
......@@ -121,13 +122,13 @@ static char version[] __devinitdata =
#define CHECK_WBACK(addr,len) \
do { if (!dma_consistent) dma_cache_wback((unsigned long)addr,len); } while (0)
do { dma_cache_sync((void *)addr, len, DMA_TO_DEVICE); } while (0)
#define CHECK_INV(addr,len) \
do { if (!dma_consistent) dma_cache_inv((unsigned long)addr,len); } while(0)
do { dma_cache_sync((void *)addr,len, DMA_FROM_DEVICE); } while(0)
#define CHECK_WBACK_INV(addr,len) \
do { if (!dma_consistent) dma_cache_wback_inv((unsigned long)addr,len); } while (0)
do { dma_cache_sync((void *)addr,len, DMA_BIDIRECTIONAL); } while (0)
#define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/
......@@ -383,6 +384,7 @@ struct i596_private {
int options;
spinlock_t lock;
dma_addr_t dma_addr;
struct device *dev;
};
static char init_setup[] =
......@@ -402,10 +404,6 @@ static char init_setup[] =
0x00,
0x7f /* *multi IA */ };
static struct pci_dev *fake_pci_dev; /* The fake pci_dev needed for
pci_* functions under ccio. */
static int dma_consistent = 1; /* Zero if pci_alloc_consistent() fails */
static int i596_open(struct net_device *dev);
static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
......@@ -558,8 +556,8 @@ static inline void init_rx_bufs(struct net_device *dev)
if (skb == NULL)
panic("82596: alloc_skb() failed");
skb_reserve(skb, 2);
dma_addr = pci_map_single(fake_pci_dev, skb->tail,PKT_BUF_SZ,
PCI_DMA_FROMDEVICE);
dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ,
DMA_FROM_DEVICE);
skb->dev = dev;
rbd->v_next = rbd+1;
rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
......@@ -605,9 +603,9 @@ static inline void remove_rx_bufs(struct net_device *dev)
for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
if (rbd->skb == NULL)
break;
pci_unmap_single(fake_pci_dev,
dma_unmap_single(lp->dev,
(dma_addr_t)WSWAPchar(rbd->b_data),
PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
PKT_BUF_SZ, DMA_FROM_DEVICE);
dev_kfree_skb(rbd->skb);
}
}
......@@ -774,7 +772,7 @@ static inline int i596_rx(struct net_device *dev)
struct sk_buff *newskb;
dma_addr_t dma_addr;
pci_unmap_single(fake_pci_dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
dma_unmap_single(lp->dev,(dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
/* Get fresh skbuff to replace filled one. */
newskb = dev_alloc_skb(PKT_BUF_SZ + 4);
if (newskb == NULL) {
......@@ -788,7 +786,7 @@ static inline int i596_rx(struct net_device *dev)
rx_in_place = 1;
rbd->skb = newskb;
newskb->dev = dev;
dma_addr = pci_map_single(fake_pci_dev, newskb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE);
rbd->v_data = newskb->tail;
rbd->b_data = WSWAPchar(dma_addr);
CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
......@@ -805,7 +803,7 @@ static inline int i596_rx(struct net_device *dev)
skb->dev = dev;
if (!rx_in_place) {
/* 16 byte align the data fields */
pci_dma_sync_single(fake_pci_dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
dma_sync_single(lp->dev, (dma_addr_t)WSWAPchar(rbd->b_data), PKT_BUF_SZ, DMA_FROM_DEVICE);
skb_reserve(skb, 2);
memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len);
}
......@@ -886,7 +884,7 @@ static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private
{
struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
struct sk_buff *skb = tx_cmd->skb;
pci_unmap_single(fake_pci_dev, tx_cmd->dma_addr, skb->len, PCI_DMA_TODEVICE);
dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE);
dev_kfree_skb(skb);
......@@ -1118,8 +1116,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
tbd->pad = 0;
tbd->size = EOF | length;
tx_cmd->dma_addr = pci_map_single(fake_pci_dev, skb->data, skb->len,
PCI_DMA_TODEVICE);
tx_cmd->dma_addr = dma_map_single(lp->dev, skb->data, skb->len,
DMA_TO_DEVICE);
tbd->data = WSWAPchar(tx_cmd->dma_addr);
DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued"));
......@@ -1156,6 +1154,8 @@ static int __devinit i82596_probe(struct net_device *dev)
{
int i;
struct i596_private *lp;
/* we're going to overwrite dev->priv, so pull the device out */
struct device *gen_dev = dev->priv;
char eth_addr[6];
dma_addr_t dma_addr;
......@@ -1198,17 +1198,11 @@ static int __devinit i82596_probe(struct net_device *dev)
printk("82596.c: MAC of HP700 LAN read from EEPROM\n");
}
dev->mem_start = (unsigned long) pci_alloc_consistent(fake_pci_dev,
sizeof(struct i596_private), &dma_addr);
dev->mem_start = (unsigned long) dma_alloc_noncoherent(gen_dev,
sizeof(struct i596_private), &dma_addr, GFP_KERNEL);
if (!dev->mem_start) {
printk("%s: Couldn't get consistent shared memory\n", dev->name);
dma_consistent = 0;
dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0);
if (!dev->mem_start) {
printk("%s: Couldn't get shared memory\n", dev->name);
return -ENOMEM;
}
dma_addr = virt_to_bus(dev->mem_start);
printk("%s: Couldn't get shared memory\n", dev->name);
return -ENOMEM;
}
ether_setup(dev);
......@@ -1243,6 +1237,7 @@ static int __devinit i82596_probe(struct net_device *dev)
lp->scb.rfd = I596_NULL;
lp->lock = SPIN_LOCK_UNLOCKED;
lp->dma_addr = dma_addr;
lp->dev = gen_dev;
CHECK_WBACK_INV(dev->mem_start, sizeof(struct i596_private));
......@@ -1320,7 +1315,7 @@ static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if ((ptr->status) & 0x1000)
lp->stats.tx_aborted_errors++;
}
pci_unmap_single(fake_pci_dev, tx_cmd->dma_addr, skb->len, PCI_DMA_TODEVICE);
dma_unmap_single(lp->dev, tx_cmd->dma_addr, skb->len, DMA_TO_DEVICE);
dev_kfree_skb_irq(skb);
tx_cmd->cmd.command = 0; /* Mark free */
......@@ -1530,8 +1525,6 @@ lan_init_chip(struct parisc_device *dev)
return -ENODEV;
}
fake_pci_dev = ccio_get_fake(dev);
if (!dev->irq) {
printk(KERN_ERR __FILE__ ": IRQ not found for i82596 at 0x%lx\n", dev->hpa);
return -ENODEV;
......@@ -1546,6 +1539,7 @@ lan_init_chip(struct parisc_device *dev)
netdevice->base_addr = dev->hpa;
netdevice->irq = dev->irq;
netdevice->init = i82596_probe;
netdevice->priv = &dev->dev;
retval = register_netdev(netdevice);
if (retval) {
......@@ -1601,13 +1595,8 @@ static void __exit lasi_82596_exit(void)
unregister_netdev(netdevice);
lp = (struct i596_private *) netdevice->priv;
if (dma_consistent)
pci_free_consistent(fake_pci_dev,
sizeof(struct i596_private),
(void *)netdevice->mem_start, lp->dma_addr);
else
free_page(netdevice->mem_start);
dma_free_noncoherent(lp->dev, sizeof(struct i596_private),
(void *)netdevice->mem_start, lp->dma_addr);
netdevice->priv = NULL;
}
......
......@@ -1555,38 +1555,6 @@ static int ccio_probe(struct parisc_device *dev)
return 0;
}
struct pci_dev * ccio_get_fake(const struct parisc_device *dev)
{
struct ioc *ioc;
dev = find_pa_parent_type(dev, HPHW_IOA);
if(!dev)
return NULL;
ioc = ccio_find_ioc(dev->hw_path);
if(!ioc)
return NULL;
if(ioc->fake_pci_dev)
return ioc->fake_pci_dev;
ioc->fake_pci_dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
if(ioc->fake_pci_dev == NULL) {
printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
return NULL;
}
memset(ioc->fake_pci_dev, 0, sizeof(struct pci_dev));
ioc->fake_pci_dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
if(ioc->fake_pci_dev->dev.platform_data == NULL) {
printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
return NULL;
}
HBA_DATA(ioc->fake_pci_dev->dev.platform_data)->iommu = ioc;
return ioc->fake_pci_dev;
}
/* We *can't* support JAVA (T600). Venture there at your own risk. */
static struct parisc_device_id ccio_tbl[] = {
{ HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */
......
......@@ -974,8 +974,8 @@ sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
*
* See Documentation/DMA-mapping.txt
*/
static void *
sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle)
static void *sba_alloc_consistent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, int gfp)
{
void *ret;
......@@ -985,7 +985,7 @@ sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle)
return 0;
}
ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
ret = (void *) __get_free_pages(gfp, get_order(size));
if (ret) {
memset(ret, 0, size);
......
......@@ -40,6 +40,7 @@
#include <linux/parport.h>
#include <asm/pdc.h>
#include <asm/parisc-device.h>
#include <asm/hardware.h>
#include <asm/parport_gsc.h>
......
......@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <asm/hardware.h>
#include <asm/parisc-device.h>
#include <asm/io.h>
#include <asm/serial.h>
......@@ -32,6 +33,7 @@ static void setup_parisc_serial(struct serial_struct *serial,
serial->type = PORT_16550A;
serial->line = line;
serial->iomap_base = address;
serial->iomem_base = ioremap(address, 0x8);
serial->irq = irq;
......@@ -91,11 +93,13 @@ static struct parisc_device_id serial_tbl[] = {
{ 0 }
};
/* Hack. Dino's serial port will get listed first on some machines.
* So we register this driver first which knows about Lasi's serial port.
* This needs to get fixed properly somehow.
/* Hack. Some machines have SERIAL_0 attached to Lasi and SERIAL_1
* attached to Dino. Unfortunately, Dino appears before Lasi in the device
* tree. To ensure that ttyS0 == SERIAL_0, we register two drivers; one
* which only knows about Lasi and then a second which will find all the
* other serial ports. HPUX ignores this problem.
*/
static struct parisc_device_id serial1_tbl[] = {
static struct parisc_device_id lasi_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
......@@ -111,9 +115,9 @@ static struct parisc_device_id serial1_tbl[] = {
MODULE_DEVICE_TABLE(parisc, serial_tbl);
static struct parisc_driver serial1_driver = {
.name = "Serial RS232",
.id_table = serial1_tbl,
static struct parisc_driver lasi_driver = {
.name = "Lasi RS232",
.id_table = lasi_tbl,
.probe = serial_init_chip,
};
......@@ -125,7 +129,7 @@ static struct parisc_driver serial_driver = {
int __init probe_serial_gsc(void)
{
register_parisc_driver(&serial1_driver);
register_parisc_driver(&lasi_driver);
register_parisc_driver(&serial_driver);
return 0;
}
......
......@@ -23,7 +23,9 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/console.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/parisc-device.h>
#ifdef CONFIG_MAGIC_SYSRQ
#include <linux/sysrq.h>
......@@ -32,34 +34,35 @@
#include <linux/serial_core.h>
#define MUX_NR 1
#define MUX_OFFSET 0x800
#define MUX_LINE_OFFSET 0x80
#define MUX_FIFO_SIZE 255
#define MUX_MIN_FREE_SIZE 32
#define MUX_FIFO_DRAIN_DELAY 1
#define MUX_POLL_DELAY (30 * HZ / 1000)
#define MUX_POLL_DELAY (30 * HZ / 1000)
#define IO_COMMAND_REG_OFFSET 0x30
#define IO_STATUS_REG_OFFSET 0x34
#define IO_DATA_REG_OFFSET 0x3c
#define IO_DCOUNT_REG_OFFSET 0x40
#define IO_UCOUNT_REG_OFFSET 0x44
#define IO_FIFOS_REG_OFFSET 0x48
#define MUX_EOFIFO(status) ((status & 0xF000) == 0xF000)
#define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
#define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
#define UART_NR 8
struct mux_card {
struct uart_port ports[UART_NR];
struct uart_driver drv;
struct mux_card *next;
};
static struct mux_card mux_card_head = {
.next = NULL,
};
static struct uart_port mux_ports[MUX_NR];
static struct timer_list mux_timer;
#define UART_PUT_CHAR(p, c) __raw_writel((c), (unsigned long)(p)->membase + IO_DATA_REG_OFFSET)
#define UART_GET_FIFO_CNT(p) __raw_readl((unsigned long)(p)->membase + IO_DCOUNT_REG_OFFSET)
#define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8
/**
* mux_tx_empty - Check if the transmitter fifo is empty.
......@@ -205,8 +208,8 @@ static void mux_write(struct uart_port *port)
static void mux_read(struct uart_port *port)
{
int data;
__u32 start_count = port->icount.rx;
struct tty_struct *tty = port->info->tty;
__u32 start_count = port->icount.rx;
while(1) {
data = __raw_readl((unsigned long)port->membase
......@@ -294,7 +297,7 @@ static const char *mux_type(struct uart_port *port)
}
/**
* release_port - Release memory and IO regions.
* mux_release_port - Release memory and IO regions.
* @port: Ptr to the uart_port.
*
* Release any memory and IO region resources currently in use by
......@@ -350,17 +353,26 @@ static int mux_verify_port(struct uart_port *port, struct serial_struct *ser)
}
/**
* mux_drv_poll - Mux poll function.
* mux_drv_poll - Mux poll function.
* @unused: Unused variable
*
* This function periodically polls the Serial MUX to check for new data.
*/
static void mux_poll(unsigned long unused)
{
struct uart_port *port = &mux_ports[0];
int i;
struct mux_card *card = &mux_card_head;
while(card) {
for(i = 0; i < UART_NR; ++i) {
if(!card->ports[i].info)
continue;
mux_read(port);
mux_write(port);
mux_read(&card->ports[i]);
mux_write(&card->ports[i]);
}
card = card->next;
}
mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
}
......@@ -395,20 +407,6 @@ static struct uart_ops mux_pops = {
.verify_port = mux_verify_port,
};
static struct uart_driver mux_reg = {
.owner = THIS_MODULE,
.driver_name = "ttyB",
#ifdef CONFIG_DEVFS_FS
.dev_name = "ttyB%d",
#else
.dev_name = "ttyB%d",
#endif
.major = MUX_MAJOR,
.minor = 0,
.nr = MUX_NR,
.cons = MUX_CONSOLE,
};
/**
* mux_probe - Determine if the Serial Mux should claim this device.
* @dev: The parisc device.
......@@ -418,36 +416,77 @@ static struct uart_driver mux_reg = {
*/
static int __init mux_probe(struct parisc_device *dev)
{
int i, ret;
struct uart_port *port = &mux_ports[0];
init_timer(&mux_timer);
mux_timer.function = mux_poll;
printk(KERN_INFO "Serial mux driver Revision: 0.1\n");
ret = uart_register_driver(&mux_reg);
if (ret)
return ret;
for (i = 0; i < MUX_NR; i++) {
port = &mux_ports[i];
port->iobase = 0;
port->mapbase = dev->hpa + MUX_OFFSET + (i * MUX_LINE_OFFSET);
port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET);
port->iotype = SERIAL_IO_MEM;
port->type = PORT_MUX;
port->irq = SERIAL_IRQ_NONE;
port->uartclk = 0;
port->fifosize = MUX_FIFO_SIZE;
port->ops = &mux_pops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = 0;
uart_add_one_port(&mux_reg, port);
int i, j, ret, ports, port_cnt = 0;
u8 iodc_data[8];
unsigned long bytecnt;
struct uart_port *port;
struct mux_card *card = &mux_card_head;
ret = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 8);
if(ret != PDC_OK) {
printk(KERN_ERR "Serial mux: Unable to read IODC.\n");
return 1;
}
ports = GET_MUX_PORTS(iodc_data);
printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.2\n",
ports);
if(!card->drv.nr) {
init_timer(&mux_timer);
mux_timer.function = mux_poll;
} else {
port_cnt += UART_NR;
while(card->next) {
card = card->next;
port_cnt += UART_NR;
}
}
for(i = 0; i < ports / UART_NR; ++i) {
if(card->drv.nr) {
card->next = kmalloc(sizeof(struct mux_card), GFP_KERNEL);
if(!card->next) {
printk(KERN_ERR "Serial mux: Unable to allocate memory.\n");
return 1;
}
memset(card->next, '\0', sizeof(struct mux_card));
card = card->next;
}
card->drv.owner = THIS_MODULE;
card->drv.driver_name = "ttyB";
card->drv.dev_name = "ttyB%d";
card->drv.major = MUX_MAJOR;
card->drv.minor = port_cnt;
card->drv.nr = UART_NR;
card->drv.cons = MUX_CONSOLE;
ret = uart_register_driver(&card->drv);
if(ret) {
printk(KERN_ERR "Serial mux: Unable to register driver.\n");
return 1;
}
for(j = 0; j < UART_NR; ++j) {
port = &card->ports[j];
port->iobase = 0;
port->mapbase = dev->hpa + MUX_OFFSET + (j * MUX_LINE_OFFSET);
port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET);
port->iotype = SERIAL_IO_MEM;
port->type = PORT_MUX;
port->irq = SERIAL_IRQ_NONE;
port->uartclk = 0;
port->fifosize = MUX_FIFO_SIZE;
port->ops = &mux_pops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = j;
ret = uart_add_one_port(&card->drv, port);
BUG_ON(ret);
}
port_cnt += UART_NR;
}
return 0;
}
......@@ -459,9 +498,9 @@ static struct parisc_device_id mux_tbl[] = {
MODULE_DEVICE_TABLE(parisc, mux_tbl);
static struct parisc_driver mux_driver = {
.name = "Serial MUX driver",
.id_table = mux_tbl,
.probe = mux_probe,
.name = "Serial MUX",
.id_table = mux_tbl,
.probe = mux_probe,
};
/**
......@@ -482,12 +521,13 @@ static int __init mux_init(void)
static void __exit mux_exit(void)
{
int i;
struct mux_card *card = &mux_card_head;
for (i = 0; i < MUX_NR; i++) {
uart_remove_one_port(&mux_reg, &mux_ports[i]);
for (i = 0; i < UART_NR; i++) {
uart_remove_one_port(&card->drv, &card->ports[i]);
}
uart_unregister_driver(&mux_reg);
uart_unregister_driver(&card->drv);
}
module_init(mux_init);
......
......@@ -56,7 +56,7 @@ static int som_core_dump(long signr, struct pt_regs * regs);
static struct linux_binfmt som_format = {
.module = THIS_MODULE,
.load_binary = load_som_binary,
.load_library = load_som_library,
.load_shlib = load_som_library,
.core_dump = som_core_dump,
.min_coredump = SOM_PAGESIZE
};
......
......@@ -257,7 +257,14 @@ static __inline__ int ffs(int x)
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
*/
#define hweight64(x) \
({ \
unsigned long __x = (x); \
unsigned int __w; \
__w = generic_hweight32((unsigned int) __x); \
__w += generic_hweight32((unsigned int) (__x>>32)); \
__w; \
})
#define hweight32(x) generic_hweight32(x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
......
......@@ -72,4 +72,24 @@ struct compat_flock {
compat_pid_t l_pid;
};
struct compat_statfs {
s32 f_type;
s32 f_bsize;
s32 f_blocks;
s32 f_bfree;
s32 f_bavail;
s32 f_files;
s32 f_ffree;
__kernel_fsid_t f_fsid;
s32 f_namelen;
s32 f_spare[6];
};
typedef u32 compat_old_sigset_t; /* at least 32 bits */
#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW BITS_PER_LONG
typedef u32 compat_sigset_word;
#endif /* _ASM_PARISC_COMPAT_H */
......@@ -203,7 +203,6 @@ parisc_walk_tree(struct device *dev)
struct parisc_device;
struct ioc;
void * ccio_get_iommu(const struct parisc_device *dev);
struct pci_dev * ccio_get_fake(const struct parisc_device *dev);
int ccio_request_resource(const struct parisc_device *dev,
struct resource *res);
int ccio_allocate_resource(const struct parisc_device *dev,
......@@ -213,7 +212,6 @@ int ccio_allocate_resource(const struct parisc_device *dev,
void *alignf_data);
#else /* !CONFIG_IOMMU_CCIO */
#define ccio_get_iommu(dev) NULL
#define ccio_get_fake(dev) NULL
#define ccio_request_resource(dev, res) request_resource(&iomem_resource, res)
#define ccio_allocate_resource(dev, res, size, min, max, align, alignf, data) \
allocate_resource(&iomem_resource, res, size, min, max, \
......
......@@ -7,10 +7,14 @@
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Addr Elf64_Addr
#define Elf_Rela Elf64_Rela
#else
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Addr Elf32_Addr
#define Elf_Rela Elf32_Rela
#endif
#define module_map(x) vmalloc(x)
......@@ -20,6 +24,10 @@
struct mod_arch_specific
{
unsigned long got_offset;
unsigned long fdesc_offset, fdesc_count;
unsigned long stub_offset;
unsigned long stub_count;
};
#endif /* _ASM_PARISC_MODULE_H */
......@@ -12,6 +12,7 @@
#define PDC_OS_BOOT_RENDEZVOUS_HI 0x28
#ifndef ASSEMBLY
#include <linux/bitops.h>
#include <linux/threads.h> /* for NR_CPUS */
typedef unsigned long address_t;
......@@ -53,7 +54,7 @@ extern unsigned long cpu_present_mask;
#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
#define cpu_possible(cpu) (cpu_present_mask & (1<<(cpu)))
extern inline unsigned int num_online_cpus(void)
{
return hweight32(cpu_online_map);
......
......@@ -519,6 +519,174 @@ typedef struct {
#define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */
/* HPPA specific definitions. */
/* Legal values for e_flags field of Elf32_Ehdr. */
#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
prediction. */
#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
/* Additional section indeces. */
#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
symbols in ANSI C. */
#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
/* Legal values for sh_type field of Elf32_Shdr. */
#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
/* Legal values for sh_flags field of Elf32_Shdr. */
#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
/* Legal values for ST_TYPE subfield of st_info (symbol type). */
#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
#define STT_HP_OPAQUE (STT_LOOS + 0x1)
#define STT_HP_STUB (STT_LOOS + 0x2)
/* HPPA relocs. */
#define R_PARISC_NONE 0 /* No reloc. */
#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
#define R_PARISC_FPTR64 64 /* 64 bits function address. */
#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
#define R_PARISC_LORESERVE 128
#define R_PARISC_COPY 128 /* Copy relocation. */
#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
#define R_PARISC_HIRESERVE 255
/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
#define PT_HP_TLS (PT_LOOS + 0x0)
#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
#define PT_HP_PARALLEL (PT_LOOS + 0x10)
#define PT_HP_FASTBIND (PT_LOOS + 0x11)
#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
#define PT_HP_STACK (PT_LOOS + 0x14)
#define PT_PARISC_ARCHEXT 0x70000000
#define PT_PARISC_UNWIND 0x70000001
/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
#define PF_PARISC_SBP 0x08000000
#define PF_HP_PAGE_SIZE 0x00100000
#define PF_HP_FAR_SHARED 0x00200000
#define PF_HP_NEAR_SHARED 0x00400000
#define PF_HP_CODE 0x01000000
#define PF_HP_MODIFY 0x02000000
#define PF_HP_LAZYSWAP 0x04000000
#define PF_HP_SBP 0x08000000
typedef struct elf32_rel {
Elf32_Addr r_offset;
......
......@@ -582,7 +582,10 @@
#define PCI_DEVICE_ID_SI_7016 0x7016
#define PCI_VENDOR_ID_HP 0x103c
#define PCI_DEVICE_ID_HP_DONNER_GFX 0x1008
#define PCI_DEVICE_ID_HP_VISUALIZE_EG 0x1005
#define PCI_DEVICE_ID_HP_VISUALIZE_FX6 0x1006
#define PCI_DEVICE_ID_HP_VISUALIZE_FX4 0x1008
#define PCI_DEVICE_ID_HP_VISUALIZE_FX2 0x100a
#define PCI_DEVICE_ID_HP_TACHYON 0x1028
#define PCI_DEVICE_ID_HP_TACHLITE 0x1029
#define PCI_DEVICE_ID_HP_J2585A 0x1030
......@@ -591,6 +594,7 @@
#define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049
#define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A
#define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B
#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b
#define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223
#define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226
#define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227
......
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