Commit 1d0e901f authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5

into nuts.ninka.net:/home/davem/src/BK/sparc-2.5
parents 9fa0108b 5b88bb8f
...@@ -41,13 +41,20 @@ core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/ ...@@ -41,13 +41,20 @@ core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/
libs-y += arch/sparc/prom/ arch/sparc/lib/ libs-y += arch/sparc/prom/ arch/sparc/lib/
# Export what is needed by arch/sparc/boot/Makefile # Export what is needed by arch/sparc/boot/Makefile
export init-y core-y drivers-y net-y libs-y HEAD # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
CORE_Y := $(core-y)
CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/
CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
LIBS_Y := $(patsubst %/, %/lib.a, $(libs-y))
export INIT_Y CORE_Y DRIVERS_Y NET_Y LIBS_Y HEAD
image: vmlinux image: vmlinux
$(MAKE) -C arch/sparc/boot image $(MAKE) -C arch/sparc/boot image
archclean: archclean:
rm -f arch/sparc/kernel/include
rm -f $(TOPDIR)/vmlinux.aout rm -f $(TOPDIR)/vmlinux.aout
-$(MAKE) -C arch/sparc/boot clean -$(MAKE) -C arch/sparc/boot clean
......
...@@ -22,8 +22,8 @@ btfixupprep: btfixupprep.c ...@@ -22,8 +22,8 @@ btfixupprep: btfixupprep.c
clean: clean:
rm -f btfixupprep piggyback tftpboot.img btfix.o btfix.s image rm -f btfixupprep piggyback tftpboot.img btfix.o btfix.s image
BTOBJS := $(HEAD) $(init-y) BTOBJS := $(HEAD) $(INIT_Y)
BTLIBS := $(core-y) $(libs-y) $(drivers-y) $(net-y) BTLIBS := $(CORE_Y) $(LIBS_Y) $(DRIVERS_Y) $(NET_Y)
# Actual linking # Actual linking
image: btfix.o image: btfix.o
......
...@@ -514,7 +514,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba) ...@@ -514,7 +514,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba)
mmu_inval_dma_area(va, len_total); mmu_inval_dma_area(va, len_total);
#if 1 #if 0
/* P3 */ printk("pci_alloc_consistent: kva %lx uncva %lx phys %lx size %x\n", /* P3 */ printk("pci_alloc_consistent: kva %lx uncva %lx phys %lx size %x\n",
(long)va, (long)res->start, (long)virt_to_phys(va), len_total); (long)va, (long)res->start, (long)virt_to_phys(va), len_total);
#endif #endif
......
...@@ -269,6 +269,21 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, ...@@ -269,6 +269,21 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT); return do_mmap2(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
} }
extern int sys_remap_file_pages(unsigned long start, unsigned long size,
unsigned long prot, unsigned long pgoff,
unsigned long flags);
int sparc_remap_file_pages(unsigned long start, unsigned long size,
unsigned long prot, unsigned long pgoff,
unsigned long flags)
{
/* This works on an existing mmap so we don't need to validate
* the range as that was done at the original mmap call.
*/
return sys_remap_file_pages(start, size, prot,
(pgoff >> (PAGE_SHIFT - 12)), flags);
}
extern unsigned long do_mremap(unsigned long addr, extern unsigned long do_mremap(unsigned long addr,
unsigned long old_len, unsigned long new_len, unsigned long old_len, unsigned long new_len,
unsigned long flags, unsigned long new_addr); unsigned long flags, unsigned long new_addr);
......
...@@ -56,7 +56,7 @@ sys_call_table: ...@@ -56,7 +56,7 @@ sys_call_table:
/*175*/ .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr /*175*/ .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module /*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
/*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname /*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
/*190*/ .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*190*/ .long sys_init_module, sys_personality, sparc_remap_file_pages, sys_nis_syscall, sys_nis_syscall
/*195*/ .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask /*195*/ .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
/*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir /*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
/*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall /*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall
......
...@@ -292,7 +292,7 @@ void __init sun4c_probe_vac(void) ...@@ -292,7 +292,7 @@ void __init sun4c_probe_vac(void)
switch (idprom->id_machtype) { switch (idprom->id_machtype) {
case (SM_SUN4|SM_4_110): case (SM_SUN4|SM_4_110):
sun4c_vacinfo.type = NONE; sun4c_vacinfo.type = VAC_NONE;
sun4c_vacinfo.num_bytes = 0; sun4c_vacinfo.num_bytes = 0;
sun4c_vacinfo.linesize = 0; sun4c_vacinfo.linesize = 0;
sun4c_vacinfo.do_hwflushes = 0; sun4c_vacinfo.do_hwflushes = 0;
...@@ -301,21 +301,21 @@ void __init sun4c_probe_vac(void) ...@@ -301,21 +301,21 @@ void __init sun4c_probe_vac(void)
break; break;
case (SM_SUN4|SM_4_260): case (SM_SUN4|SM_4_260):
sun4c_vacinfo.type = WRITE_BACK; sun4c_vacinfo.type = VAC_WRITE_BACK;
sun4c_vacinfo.num_bytes = 128 * 1024; sun4c_vacinfo.num_bytes = 128 * 1024;
sun4c_vacinfo.linesize = 16; sun4c_vacinfo.linesize = 16;
sun4c_vacinfo.do_hwflushes = 0; sun4c_vacinfo.do_hwflushes = 0;
break; break;
case (SM_SUN4|SM_4_330): case (SM_SUN4|SM_4_330):
sun4c_vacinfo.type = WRITE_THROUGH; sun4c_vacinfo.type = VAC_WRITE_THROUGH;
sun4c_vacinfo.num_bytes = 128 * 1024; sun4c_vacinfo.num_bytes = 128 * 1024;
sun4c_vacinfo.linesize = 16; sun4c_vacinfo.linesize = 16;
sun4c_vacinfo.do_hwflushes = 0; sun4c_vacinfo.do_hwflushes = 0;
break; break;
case (SM_SUN4|SM_4_470): case (SM_SUN4|SM_4_470):
sun4c_vacinfo.type = WRITE_BACK; sun4c_vacinfo.type = VAC_WRITE_BACK;
sun4c_vacinfo.num_bytes = 128 * 1024; sun4c_vacinfo.num_bytes = 128 * 1024;
sun4c_vacinfo.linesize = 32; sun4c_vacinfo.linesize = 32;
sun4c_vacinfo.do_hwflushes = 0; sun4c_vacinfo.do_hwflushes = 0;
...@@ -326,7 +326,7 @@ void __init sun4c_probe_vac(void) ...@@ -326,7 +326,7 @@ void __init sun4c_probe_vac(void)
prom_halt(); prom_halt();
}; };
} else { } else {
sun4c_vacinfo.type = WRITE_THROUGH; sun4c_vacinfo.type = VAC_WRITE_THROUGH;
if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
(idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
#include <linux/lvm.h> #include <linux/lvm.h>
#endif /* LVM */ #endif /* LVM */
#include <linux/dm-ioctl.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
/* Ugly hack. */ /* Ugly hack. */
...@@ -5012,6 +5013,19 @@ COMPATIBLE_IOCTL(NBD_CLEAR_QUE) ...@@ -5012,6 +5013,19 @@ COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
COMPATIBLE_IOCTL(NBD_PRINT_DEBUG) COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS) COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
COMPATIBLE_IOCTL(NBD_DISCONNECT) COMPATIBLE_IOCTL(NBD_DISCONNECT)
/* device-mapper */
COMPATIBLE_IOCTL(DM_VERSION)
COMPATIBLE_IOCTL(DM_REMOVE_ALL)
COMPATIBLE_IOCTL(DM_DEV_CREATE)
COMPATIBLE_IOCTL(DM_DEV_REMOVE)
COMPATIBLE_IOCTL(DM_DEV_RELOAD)
COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
COMPATIBLE_IOCTL(DM_DEV_RENAME)
COMPATIBLE_IOCTL(DM_DEV_DEPS)
COMPATIBLE_IOCTL(DM_DEV_STATUS)
COMPATIBLE_IOCTL(DM_TARGET_STATUS)
COMPATIBLE_IOCTL(DM_TARGET_WAIT)
/* And these ioctls need translation */ /* And these ioctls need translation */
HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob) HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob) HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
......
...@@ -42,7 +42,7 @@ sys32_mknod: ...@@ -42,7 +42,7 @@ sys32_mknod:
and %o2, %g2, %o2 and %o2, %g2, %o2
.align 32 .align 32
.globl sys32_sendto, sys32_recvfrom, sys32_getsockopt .globl sys32_sendto, sys32_recvfrom
sys32_sendto: sys32_sendto:
sethi %hi(sys_sendto), %g1 sethi %hi(sys_sendto), %g1
jmpl %g1 + %lo(sys_sendto), %g0 jmpl %g1 + %lo(sys_sendto), %g0
...@@ -52,10 +52,6 @@ sys32_recvfrom: ...@@ -52,10 +52,6 @@ sys32_recvfrom:
sethi %hi(sys_recvfrom), %g1 sethi %hi(sys_recvfrom), %g1
jmpl %g1 + %lo(sys_recvfrom), %g0 jmpl %g1 + %lo(sys_recvfrom), %g0
srl %o5, 0, %o5 srl %o5, 0, %o5
sys32_getsockopt:
sethi %hi(sys_getsockopt), %g1
jmpl %g1 + %lo(sys_getsockopt), %g0
srl %o4, 0, %o4
.globl sys32_bdflush .globl sys32_bdflush
sys32_bdflush: sys32_bdflush:
......
...@@ -2731,12 +2731,34 @@ static int do_set_icmpv6_filter(int fd, int level, int optname, ...@@ -2731,12 +2731,34 @@ static int do_set_icmpv6_filter(int fd, int level, int optname,
return ret; return ret;
} }
static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int optlen)
{
struct timeval32 *up = (struct timeval32 *) optval;
struct timeval ktime;
mm_segment_t old_fs;
int err;
if (optlen < sizeof(*up))
return -EINVAL;
if (get_user(ktime.tv_sec, &up->tv_sec) ||
__get_user(ktime.tv_usec, &up->tv_usec))
return -EFAULT;
old_fs = get_fs();
set_fs(KERNEL_DS);
err = sys_setsockopt(fd, level, optname, (char *) &ktime, sizeof(ktime));
set_fs(old_fs);
return err;
}
asmlinkage int sys32_setsockopt(int fd, int level, int optname, asmlinkage int sys32_setsockopt(int fd, int level, int optname,
char *optval, int optlen) char *optval, int optlen)
{ {
if (optname == SO_ATTACH_FILTER) if (optname == SO_ATTACH_FILTER)
return do_set_attach_filter(fd, level, optname, return do_set_attach_filter(fd, level, optname,
optval, optlen); optval, optlen);
if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
return do_set_sock_timeout(fd, level, optname, optval, optlen);
if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER) if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
return do_set_icmpv6_filter(fd, level, optname, return do_set_icmpv6_filter(fd, level, optname,
optval, optlen); optval, optlen);
...@@ -2744,6 +2766,43 @@ asmlinkage int sys32_setsockopt(int fd, int level, int optname, ...@@ -2744,6 +2766,43 @@ asmlinkage int sys32_setsockopt(int fd, int level, int optname,
return sys_setsockopt(fd, level, optname, optval, optlen); return sys_setsockopt(fd, level, optname, optval, optlen);
} }
extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
char *optval, int *optlen);
static int do_get_sock_timeout(int fd, int level, int optname, char *optval, int *optlen)
{
struct timeval32 *up = (struct timeval32 *) optval;
struct timeval ktime;
mm_segment_t old_fs;
int len, err;
if (get_user(len, optlen))
return -EFAULT;
if (len < sizeof(*up))
return -EINVAL;
len = sizeof(ktime);
old_fs = get_fs();
set_fs(KERNEL_DS);
err = sys_getsockopt(fd, level, optname, (char *) &ktime, &len);
set_fs(old_fs);
if (!err) {
if (put_user(sizeof(*up), optlen) ||
put_user(ktime.tv_sec, &up->tv_sec) ||
__put_user(ktime.tv_usec, &up->tv_usec))
err = -EFAULT;
}
return err;
}
asmlinkage int sys32_getsockopt(int fd, int level, int optname,
char *optval, int *optlen)
{
if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
return do_get_sock_timeout(fd, level, optname, optval, optlen);
return sys_getsockopt(fd, level, optname, optval, optlen);
}
extern void check_pending(int signum); extern void check_pending(int signum);
asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact) asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
......
...@@ -57,7 +57,7 @@ sys_call_table32: ...@@ -57,7 +57,7 @@ sys_call_table32:
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
/*190*/ .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir /*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
.word sys32_readahead, sys32_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall .word sys32_readahead, sys32_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall
...@@ -116,7 +116,7 @@ sys_call_table: ...@@ -116,7 +116,7 @@ sys_call_table:
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
/*190*/ .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*190*/ .word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
.word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_nis_syscall
......
...@@ -1524,6 +1524,8 @@ void do_div0(struct pt_regs *regs) ...@@ -1524,6 +1524,8 @@ void do_div0(struct pt_regs *regs)
{ {
siginfo_t info; siginfo_t info;
if (regs->tstate & TSTATE_PRIV)
die_if_kernel("TL0: Kernel divide by zero.", regs);
if (test_thread_flag(TIF_32BIT)) { if (test_thread_flag(TIF_32BIT)) {
regs->tpc &= 0xffffffff; regs->tpc &= 0xffffffff;
regs->tnpc &= 0xffffffff; regs->tnpc &= 0xffffffff;
......
...@@ -1136,7 +1136,7 @@ static int __init detect_one_esp(Scsi_Host_Template *tpnt, struct sbus_dev *esp_ ...@@ -1136,7 +1136,7 @@ static int __init detect_one_esp(Scsi_Host_Template *tpnt, struct sbus_dev *esp_
#include <asm/sun4paddr.h> #include <asm/sun4paddr.h>
int __init esp_detect(Scsi_Host_Template *tpnt) static int __init esp_detect(Scsi_Host_Template *tpnt)
{ {
static struct sbus_dev esp_dev; static struct sbus_dev esp_dev;
int esps_in_use = 0; int esps_in_use = 0;
...@@ -1161,7 +1161,7 @@ int __init esp_detect(Scsi_Host_Template *tpnt) ...@@ -1161,7 +1161,7 @@ int __init esp_detect(Scsi_Host_Template *tpnt)
#else /* !CONFIG_SUN4 */ #else /* !CONFIG_SUN4 */
int __init esp_detect(Scsi_Host_Template *tpnt) static int __init esp_detect(Scsi_Host_Template *tpnt)
{ {
struct sbus_bus *sbus; struct sbus_bus *sbus;
struct sbus_dev *esp_dev, *sbdev_iter; struct sbus_dev *esp_dev, *sbdev_iter;
...@@ -1385,8 +1385,8 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len) ...@@ -1385,8 +1385,8 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
} }
/* ESP proc filesystem code. */ /* ESP proc filesystem code. */
int esp_proc_info(char *buffer, char **start, off_t offset, int length, static int esp_proc_info(char *buffer, char **start, off_t offset,
int hostno, int inout) int length, int hostno, int inout)
{ {
struct esp *esp; struct esp *esp;
...@@ -1830,7 +1830,7 @@ static void esp_exec_cmd(struct esp *esp) ...@@ -1830,7 +1830,7 @@ static void esp_exec_cmd(struct esp *esp)
} }
/* Queue a SCSI command delivered from the mid-level Linux SCSI code. */ /* Queue a SCSI command delivered from the mid-level Linux SCSI code. */
int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) static int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{ {
struct esp *esp; struct esp *esp;
...@@ -1867,7 +1867,7 @@ int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -1867,7 +1867,7 @@ int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
} }
/* Only queuing supported in this ESP driver. */ /* Only queuing supported in this ESP driver. */
int esp_command(Scsi_Cmnd *SCpnt) static int esp_command(Scsi_Cmnd *SCpnt)
{ {
struct esp *esp = (struct esp *) SCpnt->host->hostdata; struct esp *esp = (struct esp *) SCpnt->host->hostdata;
...@@ -1932,7 +1932,7 @@ static void esp_dump_state(struct esp *esp) ...@@ -1932,7 +1932,7 @@ static void esp_dump_state(struct esp *esp)
} }
/* Abort a command. */ /* Abort a command. */
int esp_abort(Scsi_Cmnd *SCptr) static int esp_abort(Scsi_Cmnd *SCptr)
{ {
struct esp *esp = (struct esp *) SCptr->host->hostdata; struct esp *esp = (struct esp *) SCptr->host->hostdata;
unsigned long flags; unsigned long flags;
...@@ -2068,7 +2068,7 @@ static int esp_do_resetbus(struct esp *esp) ...@@ -2068,7 +2068,7 @@ static int esp_do_resetbus(struct esp *esp)
/* Reset ESP chip, reset hanging bus, then kill active and /* Reset ESP chip, reset hanging bus, then kill active and
* disconnected commands for targets without soft reset. * disconnected commands for targets without soft reset.
*/ */
int esp_reset(Scsi_Cmnd *SCptr) static int esp_reset(Scsi_Cmnd *SCptr)
{ {
struct esp *esp = (struct esp *) SCptr->host->hostdata; struct esp *esp = (struct esp *) SCptr->host->hostdata;
unsigned long flags; unsigned long flags;
...@@ -4359,7 +4359,7 @@ static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs) ...@@ -4359,7 +4359,7 @@ static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
spin_unlock_irqrestore(esp->ehost->host_lock, flags); spin_unlock_irqrestore(esp->ehost->host_lock, flags);
} }
void esp_slave_detach(Scsi_Device* SDptr) static void esp_slave_detach(Scsi_Device* SDptr)
{ {
struct esp *esp = (struct esp *) SDptr->host->hostdata; struct esp *esp = (struct esp *) SDptr->host->hostdata;
esp->targets_present &= ~(1 << SDptr->id); esp->targets_present &= ~(1 << SDptr->id);
...@@ -4368,7 +4368,27 @@ void esp_slave_detach(Scsi_Device* SDptr) ...@@ -4368,7 +4368,27 @@ void esp_slave_detach(Scsi_Device* SDptr)
SDptr->hostdata = NULL; SDptr->hostdata = NULL;
} }
static Scsi_Host_Template driver_template = SCSI_SPARC_ESP;
#include "scsi_module.c" static Scsi_Host_Template driver_template = {
.proc_name = "esp",
.proc_info = esp_proc_info,
.name = "Sun ESP 100/100a/200",
.detect = esp_detect,
.slave_detach = esp_slave_detach,
.info = esp_info,
.command = esp_command,
.queuecommand = esp_queue,
.eh_abort_handler = esp_abort,
.eh_bus_reset_handler = esp_reset,
.can_queue = 7,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
/* Sparc32's iommu code cannot handle highmem pages yet. */
#ifdef CONFIG_SPARC64
.highmem_io = 1,
#endif
};
#include "scsi_module.c"
...@@ -403,42 +403,6 @@ struct esp { ...@@ -403,42 +403,6 @@ struct esp {
#define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000)) #define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000))
#define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000)) #define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000))
extern int esp_detect(struct SHT *);
extern const char *esp_info(struct Scsi_Host *);
extern int esp_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
extern int esp_command(Scsi_Cmnd *);
extern int esp_abort(Scsi_Cmnd *);
extern int esp_reset(Scsi_Cmnd *);
extern int esp_proc_info(char *buffer, char **start, off_t offset, int length,
int hostno, int inout);
extern void esp_slave_detach(Scsi_Device* SDptr);
#ifdef CONFIG_SPARC64
#define ESP_HIGHMEM_IO 1
#else
/* Sparc32's iommu code cannot handle highmem pages yet. */
#define ESP_HIGHMEM_IO 0
#endif
#define SCSI_SPARC_ESP { \
.proc_name = "esp", \
.proc_info = &esp_proc_info, \
.name = "Sun ESP 100/100a/200", \
.detect = esp_detect, \
.slave_detach = esp_slave_detach, \
.info = esp_info, \
.command = esp_command, \
.queuecommand = esp_queue, \
.eh_abort_handler = esp_abort, \
.eh_bus_reset_handler = esp_reset, \
.can_queue = 7, \
.this_id = 7, \
.sg_tablesize = SG_ALL, \
.cmd_per_lun = 1, \
.use_clustering = ENABLE_CLUSTERING, \
.highmem_io = ESP_HIGHMEM_IO, \
}
/* For our interrupt engine. */ /* For our interrupt engine. */
#define for_each_esp(esp) \ #define for_each_esp(esp) \
for((esp) = espchain; (esp); (esp) = (esp)->next) for((esp) = espchain; (esp); (esp) = (esp)->next)
......
...@@ -807,7 +807,7 @@ static int __init qpti_map_queues(struct qlogicpti *qpti) ...@@ -807,7 +807,7 @@ static int __init qpti_map_queues(struct qlogicpti *qpti)
} }
/* Detect all PTI Qlogic ISP's in the machine. */ /* Detect all PTI Qlogic ISP's in the machine. */
int __init qlogicpti_detect(Scsi_Host_Template *tpnt) static int __init qlogicpti_detect(Scsi_Host_Template *tpnt)
{ {
struct qlogicpti *qpti; struct qlogicpti *qpti;
struct Scsi_Host *qpti_host; struct Scsi_Host *qpti_host;
...@@ -946,7 +946,7 @@ int __init qlogicpti_detect(Scsi_Host_Template *tpnt) ...@@ -946,7 +946,7 @@ int __init qlogicpti_detect(Scsi_Host_Template *tpnt)
return nqptis; return nqptis;
} }
int qlogicpti_release(struct Scsi_Host *host) static int qlogicpti_release(struct Scsi_Host *host)
{ {
struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
...@@ -1164,7 +1164,10 @@ static void ourdone(Scsi_Cmnd *Cmnd) ...@@ -1164,7 +1164,10 @@ static void ourdone(Scsi_Cmnd *Cmnd)
done(Cmnd); done(Cmnd);
} }
int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) static int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *));
static int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd,
void (*done)(Scsi_Cmnd *))
{ {
struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata; struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata;
unsigned long flags; unsigned long flags;
...@@ -1240,7 +1243,7 @@ int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) ...@@ -1240,7 +1243,7 @@ int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
* *
* "This code must fly." -davem * "This code must fly." -davem
*/ */
int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) static int qlogicpti_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
{ {
struct Scsi_Host *host = Cmnd->host; struct Scsi_Host *host = Cmnd->host;
struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata; struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
...@@ -1461,7 +1464,7 @@ static void qpti_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1461,7 +1464,7 @@ static void qpti_intr(int irq, void *dev_id, struct pt_regs *regs)
local_irq_restore(flags); local_irq_restore(flags);
} }
int qlogicpti_abort(Scsi_Cmnd *Cmnd) static int qlogicpti_abort(Scsi_Cmnd *Cmnd)
{ {
u_short param[6]; u_short param[6];
struct Scsi_Host *host = Cmnd->host; struct Scsi_Host *host = Cmnd->host;
...@@ -1503,7 +1506,7 @@ int qlogicpti_abort(Scsi_Cmnd *Cmnd) ...@@ -1503,7 +1506,7 @@ int qlogicpti_abort(Scsi_Cmnd *Cmnd)
return return_status; return return_status;
} }
int qlogicpti_reset(Scsi_Cmnd *Cmnd) static int qlogicpti_reset(Scsi_Cmnd *Cmnd)
{ {
u_short param[6]; u_short param[6];
struct Scsi_Host *host = Cmnd->host; struct Scsi_Host *host = Cmnd->host;
...@@ -1532,6 +1535,23 @@ int qlogicpti_reset(Scsi_Cmnd *Cmnd) ...@@ -1532,6 +1535,23 @@ int qlogicpti_reset(Scsi_Cmnd *Cmnd)
return return_status; return return_status;
} }
static Scsi_Host_Template driver_template = QLOGICPTI; static Scsi_Host_Template driver_template = {
.detect = qlogicpti_detect,
.release = qlogicpti_release,
.info = qlogicpti_info,
.queuecommand = qlogicpti_queuecommand_slow,
.eh_abort_handler = qlogicpti_abort,
.eh_bus_reset_handler = qlogicpti_reset,
.can_queue = QLOGICPTI_REQ_QUEUE_LEN,
.this_id = 7,
.sg_tablesize = QLOGICPTI_MAX_SG(QLOGICPTI_REQ_QUEUE_LEN),
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
/* Sparc32's iommu code cannot handle highmem pages yet. */
#ifdef CONFIG_SPARC64
.highmem_io = 1,
#endif
};
#include "scsi_module.c" #include "scsi_module.c"
...@@ -47,18 +47,6 @@ ...@@ -47,18 +47,6 @@
#define QLOGICPTI_REQ_QUEUE_LEN 255 /* must be power of two - 1 */ #define QLOGICPTI_REQ_QUEUE_LEN 255 /* must be power of two - 1 */
#define QLOGICPTI_MAX_SG(ql) (4 + ((ql) > 0) ? 7*((ql) - 1) : 0) #define QLOGICPTI_MAX_SG(ql) (4 + ((ql) > 0) ? 7*((ql) - 1) : 0)
#ifndef NULL
#define NULL (0)
#endif
int qlogicpti_detect(Scsi_Host_Template *);
int qlogicpti_release(struct Scsi_Host *);
const char * qlogicpti_info(struct Scsi_Host *);
int qlogicpti_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
int qlogicpti_queuecommand_slow(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
int qlogicpti_abort(Scsi_Cmnd *);
int qlogicpti_reset(Scsi_Cmnd *);
/* mailbox command complete status codes */ /* mailbox command complete status codes */
#define MBOX_COMMAND_COMPLETE 0x4000 #define MBOX_COMMAND_COMPLETE 0x4000
#define INVALID_COMMAND 0x4001 #define INVALID_COMMAND 0x4001
...@@ -514,28 +502,6 @@ struct qlogicpti { ...@@ -514,28 +502,6 @@ struct qlogicpti {
#define HCCTRL_B1ENAB 0x0008 /* Breakpoint 1 enable */ #define HCCTRL_B1ENAB 0x0008 /* Breakpoint 1 enable */
#define HCCTRL_B0ENAB 0x0004 /* Breakpoint 0 enable */ #define HCCTRL_B0ENAB 0x0004 /* Breakpoint 0 enable */
#ifdef CONFIG_SPARC64
#define QLOGICPTI_HIGHMEM_IO 1
#else
/* Sparc32's iommu code cannot handle highmem pages yet. */
#define QLOGICPTI_HIGHMEM_IO 0
#endif
#define QLOGICPTI { \
.detect = qlogicpti_detect, \
.release = qlogicpti_release, \
.info = qlogicpti_info, \
.queuecommand = qlogicpti_queuecommand_slow, \
.eh_abort_handler = qlogicpti_abort, \
.eh_bus_reset_handler = qlogicpti_reset, \
.can_queue = QLOGICPTI_REQ_QUEUE_LEN, \
.this_id = 7, \
.sg_tablesize = QLOGICPTI_MAX_SG(QLOGICPTI_REQ_QUEUE_LEN), \
.cmd_per_lun = 1, \
.use_clustering = ENABLE_CLUSTERING, \
.highmem_io = QLOGICPTI_HIGHMEM_IO, \
}
/* For our interrupt engine. */ /* For our interrupt engine. */
#define for_each_qlogicpti(qp) \ #define for_each_qlogicpti(qp) \
for((qp) = qptichain; (qp); (qp) = (qp)->next) for((qp) = qptichain; (qp); (qp) = (qp)->next)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* This is based on the old drivers/sbus/char/zs.c code. A lot * This is based on the old drivers/sbus/char/zs.c code. A lot
* of code has been simply moved over directly from there but * of code has been simply moved over directly from there but
* much has been rewritten. Credits therefore go out to Eddie * much has been rewritten. Credits therefore go out to Eddie
* C. Dost, Peter Zaitcev, Ted Ts'o and Alex Buell for their * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their
* work there. * work there.
* *
* Copyright (C) 2002 David S. Miller (davem@redhat.com) * Copyright (C) 2002 David S. Miller (davem@redhat.com)
...@@ -992,7 +992,6 @@ static struct uart_ops sunzilog_pops = { ...@@ -992,7 +992,6 @@ static struct uart_ops sunzilog_pops = {
static struct uart_sunzilog_port *sunzilog_port_table; static struct uart_sunzilog_port *sunzilog_port_table;
static struct zilog_layout **sunzilog_chip_regs; static struct zilog_layout **sunzilog_chip_regs;
static int *sunzilog_nodes;
static struct uart_sunzilog_port *sunzilog_irq_chain; static struct uart_sunzilog_port *sunzilog_irq_chain;
static int zilog_irq = -1; static int zilog_irq = -1;
...@@ -1025,12 +1024,8 @@ static void __init sunzilog_alloc_tables(void) ...@@ -1025,12 +1024,8 @@ static void __init sunzilog_alloc_tables(void)
alloc_one_table(NUM_CHANNELS * sizeof(struct uart_sunzilog_port)); alloc_one_table(NUM_CHANNELS * sizeof(struct uart_sunzilog_port));
sunzilog_chip_regs = (struct zilog_layout **) sunzilog_chip_regs = (struct zilog_layout **)
alloc_one_table(NUM_SUNZILOG * sizeof(struct zilog_layout *)); alloc_one_table(NUM_SUNZILOG * sizeof(struct zilog_layout *));
sunzilog_nodes = (int *)
alloc_one_table(NUM_SUNZILOG * sizeof(int));
if (sunzilog_port_table == NULL || if (sunzilog_port_table == NULL || sunzilog_chip_regs == NULL) {
sunzilog_chip_regs == NULL ||
sunzilog_nodes == NULL) {
prom_printf("sunzilog_init: Cannot alloc SunZilog tables.\n"); prom_printf("sunzilog_init: Cannot alloc SunZilog tables.\n");
prom_halt(); prom_halt();
} }
...@@ -1041,24 +1036,13 @@ static void __init sunzilog_alloc_tables(void) ...@@ -1041,24 +1036,13 @@ static void __init sunzilog_alloc_tables(void)
/* We used to attempt to use the address property of the Zilog device node /* We used to attempt to use the address property of the Zilog device node
* but that totally is not necessary on sparc64. * but that totally is not necessary on sparc64.
*/ */
static struct zilog_layout * __init get_zs_sun4u(int chip) static struct zilog_layout * __init get_zs_sun4u(int chip, int node)
{ {
unsigned long mapped_addr = 0xdeadbeefUL; unsigned long mapped_addr = 0xdeadbeefUL;
unsigned int sun4u_ino; unsigned int sun4u_ino;
int busnode, zsnode, seen; int zsnode, seen;
if (central_bus) zsnode = node;
busnode = central_bus->child->prom_node;
else
busnode = prom_searchsiblings(prom_getchild(prom_root_node), "sbus");
if (busnode == 0 || busnode == -1) {
prom_printf("SunZilog: Cannot find bus of Zilog %d in get_zs_sun4u.\n",
chip);
prom_halt();
}
zsnode = prom_getchild(busnode);
seen = 0; seen = 0;
while (zsnode) { while (zsnode) {
int slave; int slave;
...@@ -1111,7 +1095,6 @@ static struct zilog_layout * __init get_zs_sun4u(int chip) ...@@ -1111,7 +1095,6 @@ static struct zilog_layout * __init get_zs_sun4u(int chip)
((u64)zsregs[0].phys_addr); ((u64)zsregs[0].phys_addr);
} }
sunzilog_nodes[chip] = zsnode;
if (zilog_irq == -1) { if (zilog_irq == -1) {
if (central_bus) { if (central_bus) {
unsigned long iclr, imap; unsigned long iclr, imap;
...@@ -1142,31 +1125,35 @@ static struct zilog_layout * __init get_zs_sun4u(int chip) ...@@ -1142,31 +1125,35 @@ static struct zilog_layout * __init get_zs_sun4u(int chip)
return (struct zilog_layout *) mapped_addr; return (struct zilog_layout *) mapped_addr;
} }
#else /* CONFIG_SPARC64 */ #else /* CONFIG_SPARC64 */
static struct zilog_layout * __init get_zs_sun4cmd(int chip)
/*
* XXX The sun4d case is utterly screwed: it tries to re-walk the tree
* (for the 3rd time) in order to find bootbus and cpu. Streamline it.
*/
static struct zilog_layout * __init get_zs_sun4cmd(int chip, int node)
{ {
struct linux_prom_irqs irq_info[2]; struct linux_prom_irqs irq_info[2];
unsigned long mapped_addr = 0; unsigned long mapped_addr = 0;
int zsnode, chipid, cpunode, bbnode; int zsnode, cpunode, bbnode;
struct linux_prom_registers zsreg[4];
struct resource res;
if (sparc_cpu_model == sun4d) { if (sparc_cpu_model == sun4d) {
int walk, no; int walk;
zsnode = 0; zsnode = 0;
bbnode = 0; bbnode = 0;
no = 0; cpunode = 0;
for (walk = prom_getchild(prom_root_node); for (walk = prom_getchild(prom_root_node);
(walk = prom_searchsiblings(walk, "cpu-unit")) != 0; (walk = prom_searchsiblings(walk, "cpu-unit")) != 0;
walk = prom_getsibling(walk)) { walk = prom_getsibling(walk)) {
bbnode = prom_getchild(walk); bbnode = prom_getchild(walk);
if (bbnode && if (bbnode &&
(bbnode = prom_searchsiblings(bbnode, "bootbus"))) { (bbnode = prom_searchsiblings(bbnode, "bootbus"))) {
if (no == (chip / 2)) { if ((zsnode = prom_getchild(bbnode)) == node) {
cpunode = walk; cpunode = walk;
zsnode = prom_getchild(bbnode);
chipid = (chip & 1);
break; break;
} }
no++;
} }
} }
if (!walk) { if (!walk) {
...@@ -1174,80 +1161,61 @@ static struct zilog_layout * __init get_zs_sun4cmd(int chip) ...@@ -1174,80 +1161,61 @@ static struct zilog_layout * __init get_zs_sun4cmd(int chip)
(chip / 2)); (chip / 2));
prom_halt(); prom_halt();
} }
} else {
int tmp;
zsnode = prom_getchild(prom_root_node);
if ((tmp = prom_searchsiblings(zsnode, "obio"))) {
zsnode = prom_getchild(tmp);
if (!zsnode) {
prom_printf("SunZilog: Child of obio node does "
"not exist.\n");
prom_halt();
}
}
chipid = 0;
}
while (zsnode) { if (prom_getproperty(zsnode, "reg",
struct linux_prom_registers zsreg[4]; (char *) zsreg, sizeof(zsreg)) == -1) {
struct resource res; prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
prom_halt();
}
/* XXX Looks like an off by one? */
prom_apply_generic_ranges(bbnode, cpunode, zsreg, 1);
res.start = zsreg[0].phys_addr;
res.end = res.start + (8 - 1);
res.flags = zsreg[0].which_io | IORESOURCE_IO;
mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
zsnode = prom_searchsiblings(zsnode, "zs"); } else {
if (zsnode == 0 || zsnode == -1) zsnode = node;
break;
#if 0 /* XXX When was this used? */
if (prom_getintdefault(zsnode, "slave", -1) != chipid) { if (prom_getintdefault(zsnode, "slave", -1) != chipid) {
zsnode = prom_getsibling(zsnode); zsnode = prom_getsibling(zsnode);
continue; continue;
} }
#endif
if (sparc_cpu_model == sun4d) { /*
/* Sun4d Zilog nodes lack the address property, so just * "address" is only present on ports that OBP opened
* map it like a normal device. * (from Mitch Bradley's "Hitchhiker's Guide to OBP").
*/ * We do not use it.
if (prom_getproperty(zsnode, "reg", */
(char *) zsreg, sizeof(zsreg)) == -1) {
prom_printf("SunZilog: Cannot map Zilog %d "
"regs on sun4c.\n", chip);
prom_halt();
}
prom_apply_generic_ranges(bbnode, cpunode, zsreg, 1);
res.start = zsreg[0].phys_addr;
res.end = res.start + (8 - 1);
res.flags = zsreg[0].which_io | IORESOURCE_IO;
mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
} else {
unsigned int vaddr[2];
if (prom_getproperty(zsnode, "address", if (prom_getproperty(zsnode, "reg",
(void *) vaddr, sizeof(vaddr)) (char *) zsreg, sizeof(zsreg)) == -1) {
% sizeof(unsigned int)) { prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
prom_printf("SunZilog: Cannot get address property for "
"Zilog %d.\n", chip);
prom_halt();
}
mapped_addr = (unsigned long) vaddr[0];
}
sunzilog_nodes[chip] = zsnode;
if (prom_getproperty(zsnode, "intr",
(char *) irq_info, sizeof(irq_info))
% sizeof(struct linux_prom_irqs)) {
prom_printf("SunZilog: Cannot get IRQ property for "
"Zilog %d.\n", chip);
prom_halt();
}
if (zilog_irq == -1) {
zilog_irq = irq_info[0].pri;
} else if (zilog_irq != irq_info[0].pri) {
prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
chip);
prom_halt(); prom_halt();
} }
break; if (sparc_cpu_model == sun4m) /* Crude. Pass parent. XXX */
prom_apply_obio_ranges(zsreg, 1);
res.start = zsreg[0].phys_addr;
res.end = res.start + (8 - 1);
res.flags = zsreg[0].which_io | IORESOURCE_IO;
mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
}
if (prom_getproperty(zsnode, "intr",
(char *) irq_info, sizeof(irq_info))
% sizeof(struct linux_prom_irqs)) {
prom_printf("SunZilog: Cannot get IRQ property for Zilog %d.\n",
chip);
prom_halt();
} }
if (!zsnode) { if (zilog_irq == -1) {
prom_printf("SunZilog: OBP node for Zilog %d not found.\n", chip); zilog_irq = irq_info[0].pri;
} else if (zilog_irq != irq_info[0].pri) {
/* XXX. Dumb. Should handle per-chip IRQ, for add-ons. */
prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
chip);
prom_halt(); prom_halt();
} }
...@@ -1256,7 +1224,7 @@ static struct zilog_layout * __init get_zs_sun4cmd(int chip) ...@@ -1256,7 +1224,7 @@ static struct zilog_layout * __init get_zs_sun4cmd(int chip)
#endif /* !(CONFIG_SPARC64) */ #endif /* !(CONFIG_SPARC64) */
/* Get the address of the registers for SunZilog instance CHIP. */ /* Get the address of the registers for SunZilog instance CHIP. */
static struct zilog_layout * __init get_zs(int chip) static struct zilog_layout * __init get_zs(int chip, int node)
{ {
if (chip < 0 || chip >= NUM_SUNZILOG) { if (chip < 0 || chip >= NUM_SUNZILOG) {
prom_printf("SunZilog: Illegal chip number %d in get_zs.\n", chip); prom_printf("SunZilog: Illegal chip number %d in get_zs.\n", chip);
...@@ -1264,7 +1232,7 @@ static struct zilog_layout * __init get_zs(int chip) ...@@ -1264,7 +1232,7 @@ static struct zilog_layout * __init get_zs(int chip)
} }
#ifdef CONFIG_SPARC64 #ifdef CONFIG_SPARC64
return get_zs_sun4u(chip); return get_zs_sun4u(chip, node);
#else #else
if (sparc_cpu_model == sun4) { if (sparc_cpu_model == sun4) {
...@@ -1279,14 +1247,13 @@ static struct zilog_layout * __init get_zs(int chip) ...@@ -1279,14 +1247,13 @@ static struct zilog_layout * __init get_zs(int chip)
res.start = 0xf0000000; res.start = 0xf0000000;
break; break;
}; };
sunzilog_nodes[chip] = 0;
zilog_irq = 12; zilog_irq = 12;
res.end = (res.start + (8 - 1)); res.end = (res.start + (8 - 1));
res.flags = IORESOURCE_IO; res.flags = IORESOURCE_IO;
return (struct zilog_layout *) sbus_ioremap(&res, 0, 8, "SunZilog"); return (struct zilog_layout *) sbus_ioremap(&res, 0, 8, "SunZilog");
} }
return get_zs_sun4cmd(chip); return get_zs_sun4cmd(chip, node);
#endif #endif
} }
...@@ -1459,6 +1426,52 @@ static int __init sunzilog_console_init(void) ...@@ -1459,6 +1426,52 @@ static int __init sunzilog_console_init(void)
return 0; return 0;
} }
/*
* We scan the PROM tree recursively. This is the most reliable way
* to find Zilog nodes on various platforms. However, we face an extreme
* shortage of kernel stack, so we must be very careful. To that end,
* we scan only to a certain depth, and we use a common property buffer
* in the scan structure.
*/
#define ZS_PROPSIZE 128
#define ZS_SCAN_DEPTH 5
struct zs_probe_scan {
int depth;
void (*scanner)(struct zs_probe_scan *t, int node);
int devices;
char prop[ZS_PROPSIZE];
};
static int __inline__ sunzilog_node_ok(int node, const char *name, int len)
{
if (strncmp(name, "zs", len) == 0)
return 1;
/* Don't fold this procedure just yet. Compare to su_node_ok(). */
return 0;
}
static void __init sunzilog_scan(struct zs_probe_scan *t, int node)
{
int len;
for (; node != 0; node = prom_getsibling(node)) {
len = prom_getproperty(node, "name", t->prop, ZS_PROPSIZE);
if (len <= 1)
continue; /* Broken PROM node */
if (sunzilog_node_ok(node, t->prop, len)) {
(*t->scanner)(t, node);
} else {
if (t->depth < ZS_SCAN_DEPTH) {
t->depth++;
sunzilog_scan(t, prom_getchild(node));
--t->depth;
}
}
}
}
static void __init sunzilog_prepare(void) static void __init sunzilog_prepare(void)
{ {
struct uart_sunzilog_port *up; struct uart_sunzilog_port *up;
...@@ -1471,12 +1484,9 @@ static void __init sunzilog_prepare(void) ...@@ -1471,12 +1484,9 @@ static void __init sunzilog_prepare(void)
up[channel].next = NULL; up[channel].next = NULL;
for (chip = 0; chip < NUM_SUNZILOG; chip++) { for (chip = 0; chip < NUM_SUNZILOG; chip++) {
if (!sunzilog_chip_regs[chip]) { rp = sunzilog_chip_regs[chip];
sunzilog_chip_regs[chip] = rp = get_zs(chip); up[(chip * 2) + 0].port.membase = (char *) &rp->channelA;
up[(chip * 2) + 1].port.membase = (char *) &rp->channelB;
up[(chip * 2) + 0].port.membase = (char *) &rp->channelA;
up[(chip * 2) + 1].port.membase = (char *) &rp->channelB;
}
/* Channel A */ /* Channel A */
up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM; up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM;
...@@ -1593,11 +1603,25 @@ static void __init sunzilog_init_hw(void) ...@@ -1593,11 +1603,25 @@ static void __init sunzilog_init_hw(void)
} }
} }
static struct zilog_layout * __init get_zs(int chip, int node);
static void __init sunzilog_scan_probe(struct zs_probe_scan *t, int node)
{
sunzilog_chip_regs[t->devices] = get_zs(t->devices, node);
t->devices++;
}
static int __init sunzilog_ports_init(void) static int __init sunzilog_ports_init(void)
{ {
struct zs_probe_scan scan;
int ret; int ret;
printk(KERN_INFO "Serial: Sun Zilog driver.\n"); printk(KERN_INFO "Serial: Sun Zilog driver (%d chips).\n", NUM_SUNZILOG);
scan.scanner = sunzilog_scan_probe;
scan.depth = 0;
scan.devices = 0;
sunzilog_scan(&scan, prom_getchild(prom_root_node));
sunzilog_prepare(); sunzilog_prepare();
...@@ -1635,56 +1659,34 @@ static int __init sunzilog_ports_init(void) ...@@ -1635,56 +1659,34 @@ static int __init sunzilog_ports_init(void)
return ret; return ret;
} }
static int __init sunzilog_init(void) static void __init sunzilog_scan_count(struct zs_probe_scan *t, int node)
{ {
int node; t->devices++;
}
static int __init sunzilog_ports_count(void)
{
struct zs_probe_scan scan;
/* Sun4 Zilog setup is hard coded, no probing to do. */ /* Sun4 Zilog setup is hard coded, no probing to do. */
if (sparc_cpu_model == sun4) { if (sparc_cpu_model == sun4)
NUM_SUNZILOG = 2; return 2;
} else if (sparc_cpu_model == sun4d) {
int bbnode;
node = prom_getchild(prom_root_node);
NUM_SUNZILOG = 0;
while (node &&
(node = prom_searchsiblings(node, "cpu-unit"))) {
bbnode = prom_getchild(node);
if (bbnode && prom_searchsiblings(bbnode, "bootbus"))
NUM_SUNZILOG += 2;
node = prom_getsibling(node);
}
} else if (sparc_cpu_model == sun4u) {
int central_node;
/* Central bus zilogs must be checked for first, scan.scanner = sunzilog_scan_count;
* since Enterprise boxes might have SBUSes as well. scan.depth = 0;
*/ scan.devices = 0;
central_node = prom_finddevice("/central");
if (central_node != 0 && central_node != -1) sunzilog_scan(&scan, prom_getchild(prom_root_node));
node = prom_searchsiblings(prom_getchild(central_node), "fhc");
else return scan.devices;
node = prom_searchsiblings(prom_getchild(prom_root_node), "sbus"); }
if (node != 0 && node != -1)
node = prom_getchild(node); static int __init sunzilog_init(void)
if (node == 0 || node == -1) {
return -ENODEV;
NUM_SUNZILOG = sunzilog_ports_count();
node = prom_searchsiblings(node, "zs"); if (NUM_SUNZILOG == 0)
if (!node) return -ENODEV;
return -ENODEV;
NUM_SUNZILOG = 2;
} else {
node = prom_getchild(prom_root_node);
node = prom_searchsiblings(node, "obio");
if (node)
node = prom_getchild(node);
if (!node)
return -ENODEV;
NUM_SUNZILOG = 2;
}
sunzilog_alloc_tables(); sunzilog_alloc_tables();
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#define POLLRDBAND 128 #define POLLRDBAND 128
#define POLLWRBAND 256 #define POLLWRBAND 256
#define POLLMSG 512 #define POLLMSG 512
#define POLLREMOVE 1024
struct pollfd { struct pollfd {
int fd; int fd;
......
...@@ -135,7 +135,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, ...@@ -135,7 +135,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
* clobber every non-fixed-usage register besides l2/l3/o4/o5. -DaveM * clobber every non-fixed-usage register besides l2/l3/o4/o5. -DaveM
* *
* Hey Dave, that do not touch sign is too much of an incentive * Hey Dave, that do not touch sign is too much of an incentive
* - Anton * - Anton & Pete
*/ */
#define switch_to(prev, next, last) do { \ #define switch_to(prev, next, last) do { \
__label__ here; \ __label__ here; \
...@@ -160,6 +160,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, ...@@ -160,6 +160,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
"wr %%g4, 0x20, %%psr\n\t" \ "wr %%g4, 0x20, %%psr\n\t" \
"nop\n\t" \ "nop\n\t" \
"nop\n\t" \ "nop\n\t" \
"nop\n\t" /* LEON needs this: load to %sp depends on CWP. */ \
"ldd [%%g6 + %4], %%sp\n\t" \ "ldd [%%g6 + %4], %%sp\n\t" \
"wr %%g5, 0x0, %%wim\n\t" \ "wr %%g5, 0x0, %%wim\n\t" \
"ldd [%%sp + 0x00], %%l0\n\t" \ "ldd [%%sp + 0x00], %%l0\n\t" \
......
...@@ -207,7 +207,7 @@ ...@@ -207,7 +207,7 @@
#define __NR_uname 189 /* Linux Specific */ #define __NR_uname 189 /* Linux Specific */
#define __NR_init_module 190 /* Linux Specific */ #define __NR_init_module 190 /* Linux Specific */
#define __NR_personality 191 /* Linux Specific */ #define __NR_personality 191 /* Linux Specific */
/* #define __NR_prof 192 Linux Specific */ #define __NR_remap_file_pages 192 /* Linux Specific */
/* #define __NR_break 193 Linux Specific */ /* #define __NR_break 193 Linux Specific */
/* #define __NR_lock 194 Linux Specific */ /* #define __NR_lock 194 Linux Specific */
/* #define __NR_mpx 195 Linux Specific */ /* #define __NR_mpx 195 Linux Specific */
......
...@@ -98,8 +98,8 @@ struct sun4c_vac_props { ...@@ -98,8 +98,8 @@ struct sun4c_vac_props {
unsigned int num_bytes; /* Size of the cache */ unsigned int num_bytes; /* Size of the cache */
unsigned int num_lines; /* Number of cache lines */ unsigned int num_lines; /* Number of cache lines */
unsigned int do_hwflushes; /* Hardware flushing available? */ unsigned int do_hwflushes; /* Hardware flushing available? */
enum { NONE, WRITE_THROUGH, enum { VAC_NONE, VAC_WRITE_THROUGH,
WRITE_BACK } type; /* What type of VAC? */ VAC_WRITE_BACK } type; /* What type of VAC? */
unsigned int linesize; /* Size of each line in bytes */ unsigned int linesize; /* Size of each line in bytes */
unsigned int log2lsize; /* log2(linesize) */ unsigned int log2lsize; /* log2(linesize) */
unsigned int on; /* VAC is enabled */ unsigned int on; /* VAC is enabled */
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#define POLLRDBAND 128 #define POLLRDBAND 128
#define POLLWRBAND 256 #define POLLWRBAND 256
#define POLLMSG 512 #define POLLMSG 512
#define POLLREMOVE 1024
struct pollfd { struct pollfd {
int fd; int fd;
......
...@@ -207,7 +207,7 @@ ...@@ -207,7 +207,7 @@
#define __NR_uname 189 /* Linux Specific */ #define __NR_uname 189 /* Linux Specific */
#define __NR_init_module 190 /* Linux Specific */ #define __NR_init_module 190 /* Linux Specific */
#define __NR_personality 191 /* Linux Specific */ #define __NR_personality 191 /* Linux Specific */
/* #define __NR_prof 192 Linux Specific */ #define __NR_remap_file_pages 192 /* Linux Specific */
/* #define __NR_break 193 Linux Specific */ /* #define __NR_break 193 Linux Specific */
/* #define __NR_lock 194 Linux Specific */ /* #define __NR_lock 194 Linux Specific */
/* #define __NR_mpx 195 Linux Specific */ /* #define __NR_mpx 195 Linux Specific */
......
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