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/
libs-y += arch/sparc/prom/ arch/sparc/lib/
# 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
$(MAKE) -C arch/sparc/boot image
archclean:
rm -f arch/sparc/kernel/include
rm -f $(TOPDIR)/vmlinux.aout
-$(MAKE) -C arch/sparc/boot clean
......
......@@ -22,8 +22,8 @@ btfixupprep: btfixupprep.c
clean:
rm -f btfixupprep piggyback tftpboot.img btfix.o btfix.s image
BTOBJS := $(HEAD) $(init-y)
BTLIBS := $(core-y) $(libs-y) $(drivers-y) $(net-y)
BTOBJS := $(HEAD) $(INIT_Y)
BTLIBS := $(CORE_Y) $(LIBS_Y) $(DRIVERS_Y) $(NET_Y)
# Actual linking
image: btfix.o
......
......@@ -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);
#if 1
#if 0
/* 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);
#endif
......
......@@ -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);
}
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,
unsigned long old_len, unsigned long new_len,
unsigned long flags, unsigned long new_addr);
......
......@@ -56,7 +56,7 @@ sys_call_table:
/*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
/*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
/*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
......
......@@ -292,7 +292,7 @@ void __init sun4c_probe_vac(void)
switch (idprom->id_machtype) {
case (SM_SUN4|SM_4_110):
sun4c_vacinfo.type = NONE;
sun4c_vacinfo.type = VAC_NONE;
sun4c_vacinfo.num_bytes = 0;
sun4c_vacinfo.linesize = 0;
sun4c_vacinfo.do_hwflushes = 0;
......@@ -301,21 +301,21 @@ void __init sun4c_probe_vac(void)
break;
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.linesize = 16;
sun4c_vacinfo.do_hwflushes = 0;
break;
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.linesize = 16;
sun4c_vacinfo.do_hwflushes = 0;
break;
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.linesize = 32;
sun4c_vacinfo.do_hwflushes = 0;
......@@ -326,7 +326,7 @@ void __init sun4c_probe_vac(void)
prom_halt();
};
} else {
sun4c_vacinfo.type = WRITE_THROUGH;
sun4c_vacinfo.type = VAC_WRITE_THROUGH;
if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
(idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
......
......@@ -55,6 +55,7 @@
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
#include <linux/lvm.h>
#endif /* LVM */
#include <linux/dm-ioctl.h>
#include <scsi/scsi.h>
/* Ugly hack. */
......@@ -5012,6 +5013,19 @@ COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS)
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 */
HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
......
......@@ -42,7 +42,7 @@ sys32_mknod:
and %o2, %g2, %o2
.align 32
.globl sys32_sendto, sys32_recvfrom, sys32_getsockopt
.globl sys32_sendto, sys32_recvfrom
sys32_sendto:
sethi %hi(sys_sendto), %g1
jmpl %g1 + %lo(sys_sendto), %g0
......@@ -52,10 +52,6 @@ sys32_recvfrom:
sethi %hi(sys_recvfrom), %g1
jmpl %g1 + %lo(sys_recvfrom), %g0
srl %o5, 0, %o5
sys32_getsockopt:
sethi %hi(sys_getsockopt), %g1
jmpl %g1 + %lo(sys_getsockopt), %g0
srl %o4, 0, %o4
.globl sys32_bdflush
sys32_bdflush:
......
......@@ -2731,12 +2731,34 @@ static int do_set_icmpv6_filter(int fd, int level, int optname,
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,
char *optval, int optlen)
{
if (optname == SO_ATTACH_FILTER)
return do_set_attach_filter(fd, level, optname,
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)
return do_set_icmpv6_filter(fd, level, optname,
optval, optlen);
......@@ -2744,6 +2766,43 @@ asmlinkage int sys32_setsockopt(int fd, int level, int optname,
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);
asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
......
......@@ -57,7 +57,7 @@ sys_call_table32:
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*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
/*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
/*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
......@@ -116,7 +116,7 @@ sys_call_table:
.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
.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
/*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
......
......@@ -1524,6 +1524,8 @@ void do_div0(struct pt_regs *regs)
{
siginfo_t info;
if (regs->tstate & TSTATE_PRIV)
die_if_kernel("TL0: Kernel divide by zero.", regs);
if (test_thread_flag(TIF_32BIT)) {
regs->tpc &= 0xffffffff;
regs->tnpc &= 0xffffffff;
......
......@@ -1136,7 +1136,7 @@ static int __init detect_one_esp(Scsi_Host_Template *tpnt, struct sbus_dev *esp_
#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;
int esps_in_use = 0;
......@@ -1161,7 +1161,7 @@ int __init esp_detect(Scsi_Host_Template *tpnt)
#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_dev *esp_dev, *sbdev_iter;
......@@ -1385,8 +1385,8 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
}
/* ESP proc filesystem code. */
int esp_proc_info(char *buffer, char **start, off_t offset, int length,
int hostno, int inout)
static int esp_proc_info(char *buffer, char **start, off_t offset,
int length, int hostno, int inout)
{
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. */
int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
static int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
{
struct esp *esp;
......@@ -1867,7 +1867,7 @@ int esp_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
}
/* 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;
......@@ -1932,7 +1932,7 @@ static void esp_dump_state(struct esp *esp)
}
/* Abort a command. */
int esp_abort(Scsi_Cmnd *SCptr)
static int esp_abort(Scsi_Cmnd *SCptr)
{
struct esp *esp = (struct esp *) SCptr->host->hostdata;
unsigned long flags;
......@@ -2068,7 +2068,7 @@ static int esp_do_resetbus(struct esp *esp)
/* Reset ESP chip, reset hanging bus, then kill active and
* 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;
unsigned long flags;
......@@ -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);
}
void esp_slave_detach(Scsi_Device* SDptr)
static void esp_slave_detach(Scsi_Device* SDptr)
{
struct esp *esp = (struct esp *) SDptr->host->hostdata;
esp->targets_present &= ~(1 << SDptr->id);
......@@ -4368,7 +4368,27 @@ void esp_slave_detach(Scsi_Device* SDptr)
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 {
#define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 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. */
#define for_each_esp(esp) \
for((esp) = espchain; (esp); (esp) = (esp)->next)
......
......@@ -807,7 +807,7 @@ static int __init qpti_map_queues(struct qlogicpti *qpti)
}
/* 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 Scsi_Host *qpti_host;
......@@ -946,7 +946,7 @@ int __init qlogicpti_detect(Scsi_Host_Template *tpnt)
return nqptis;
}
int qlogicpti_release(struct Scsi_Host *host)
static int qlogicpti_release(struct Scsi_Host *host)
{
struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
......@@ -1164,7 +1164,10 @@ static void ourdone(Scsi_Cmnd *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;
unsigned long flags;
......@@ -1240,7 +1243,7 @@ int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
*
* "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 qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
......@@ -1461,7 +1464,7 @@ static void qpti_intr(int irq, void *dev_id, struct pt_regs *regs)
local_irq_restore(flags);
}
int qlogicpti_abort(Scsi_Cmnd *Cmnd)
static int qlogicpti_abort(Scsi_Cmnd *Cmnd)
{
u_short param[6];
struct Scsi_Host *host = Cmnd->host;
......@@ -1503,7 +1506,7 @@ int qlogicpti_abort(Scsi_Cmnd *Cmnd)
return return_status;
}
int qlogicpti_reset(Scsi_Cmnd *Cmnd)
static int qlogicpti_reset(Scsi_Cmnd *Cmnd)
{
u_short param[6];
struct Scsi_Host *host = Cmnd->host;
......@@ -1532,6 +1535,23 @@ int qlogicpti_reset(Scsi_Cmnd *Cmnd)
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"
......@@ -47,18 +47,6 @@
#define QLOGICPTI_REQ_QUEUE_LEN 255 /* must be power of two - 1 */
#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 */
#define MBOX_COMMAND_COMPLETE 0x4000
#define INVALID_COMMAND 0x4001
......@@ -514,28 +502,6 @@ struct qlogicpti {
#define HCCTRL_B1ENAB 0x0008 /* Breakpoint 1 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. */
#define for_each_qlogicpti(qp) \
for((qp) = qptichain; (qp); (qp) = (qp)->next)
......
......@@ -7,7 +7,7 @@
* 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
* 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.
*
* Copyright (C) 2002 David S. Miller (davem@redhat.com)
......@@ -992,7 +992,6 @@ static struct uart_ops sunzilog_pops = {
static struct uart_sunzilog_port *sunzilog_port_table;
static struct zilog_layout **sunzilog_chip_regs;
static int *sunzilog_nodes;
static struct uart_sunzilog_port *sunzilog_irq_chain;
static int zilog_irq = -1;
......@@ -1025,12 +1024,8 @@ static void __init sunzilog_alloc_tables(void)
alloc_one_table(NUM_CHANNELS * sizeof(struct uart_sunzilog_port));
sunzilog_chip_regs = (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 ||
sunzilog_chip_regs == NULL ||
sunzilog_nodes == NULL) {
if (sunzilog_port_table == NULL || sunzilog_chip_regs == NULL) {
prom_printf("sunzilog_init: Cannot alloc SunZilog tables.\n");
prom_halt();
}
......@@ -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
* 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 int sun4u_ino;
int busnode, zsnode, seen;
int zsnode, seen;
if (central_bus)
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);
zsnode = node;
seen = 0;
while (zsnode) {
int slave;
......@@ -1111,7 +1095,6 @@ static struct zilog_layout * __init get_zs_sun4u(int chip)
((u64)zsregs[0].phys_addr);
}
sunzilog_nodes[chip] = zsnode;
if (zilog_irq == -1) {
if (central_bus) {
unsigned long iclr, imap;
......@@ -1142,31 +1125,35 @@ static struct zilog_layout * __init get_zs_sun4u(int chip)
return (struct zilog_layout *) mapped_addr;
}
#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];
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) {
int walk, no;
int walk;
zsnode = 0;
bbnode = 0;
no = 0;
cpunode = 0;
for (walk = prom_getchild(prom_root_node);
(walk = prom_searchsiblings(walk, "cpu-unit")) != 0;
walk = prom_getsibling(walk)) {
bbnode = prom_getchild(walk);
if (bbnode &&
(bbnode = prom_searchsiblings(bbnode, "bootbus"))) {
if (no == (chip / 2)) {
if ((zsnode = prom_getchild(bbnode)) == node) {
cpunode = walk;
zsnode = prom_getchild(bbnode);
chipid = (chip & 1);
break;
}
no++;
}
}
if (!walk) {
......@@ -1174,89 +1161,70 @@ static struct zilog_layout * __init get_zs_sun4cmd(int chip)
(chip / 2));
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");
if (prom_getproperty(zsnode, "reg",
(char *) zsreg, sizeof(zsreg)) == -1) {
prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
prom_halt();
}
}
chipid = 0;
}
while (zsnode) {
struct linux_prom_registers zsreg[4];
struct resource res;
/* 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");
if (zsnode == 0 || zsnode == -1)
break;
} else {
zsnode = node;
#if 0 /* XXX When was this used? */
if (prom_getintdefault(zsnode, "slave", -1) != chipid) {
zsnode = prom_getsibling(zsnode);
continue;
}
#endif
if (sparc_cpu_model == sun4d) {
/* Sun4d Zilog nodes lack the address property, so just
* map it like a normal device.
/*
* "address" is only present on ports that OBP opened
* (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_printf("SunZilog: Cannot map Zilog %d\n", chip);
prom_halt();
}
prom_apply_generic_ranges(bbnode, cpunode, zsreg, 1);
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");
} else {
unsigned int vaddr[2];
if (prom_getproperty(zsnode, "address",
(void *) vaddr, sizeof(vaddr))
% sizeof(unsigned int)) {
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_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) {
/* XXX. Dumb. Should handle per-chip IRQ, for add-ons. */
prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
chip);
prom_halt();
}
break;
}
if (!zsnode) {
prom_printf("SunZilog: OBP node for Zilog %d not found.\n", chip);
prom_halt();
}
return (struct zilog_layout *) mapped_addr;
}
#endif /* !(CONFIG_SPARC64) */
/* 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) {
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)
}
#ifdef CONFIG_SPARC64
return get_zs_sun4u(chip);
return get_zs_sun4u(chip, node);
#else
if (sparc_cpu_model == sun4) {
......@@ -1279,14 +1247,13 @@ static struct zilog_layout * __init get_zs(int chip)
res.start = 0xf0000000;
break;
};
sunzilog_nodes[chip] = 0;
zilog_irq = 12;
res.end = (res.start + (8 - 1));
res.flags = IORESOURCE_IO;
return (struct zilog_layout *) sbus_ioremap(&res, 0, 8, "SunZilog");
}
return get_zs_sun4cmd(chip);
return get_zs_sun4cmd(chip, node);
#endif
}
......@@ -1459,6 +1426,52 @@ static int __init sunzilog_console_init(void)
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)
{
struct uart_sunzilog_port *up;
......@@ -1471,12 +1484,9 @@ static void __init sunzilog_prepare(void)
up[channel].next = NULL;
for (chip = 0; chip < NUM_SUNZILOG; chip++) {
if (!sunzilog_chip_regs[chip]) {
sunzilog_chip_regs[chip] = rp = get_zs(chip);
rp = sunzilog_chip_regs[chip];
up[(chip * 2) + 0].port.membase = (char *) &rp->channelA;
up[(chip * 2) + 1].port.membase = (char *) &rp->channelB;
}
/* Channel A */
up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM;
......@@ -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)
{
struct zs_probe_scan scan;
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();
......@@ -1635,56 +1659,34 @@ static int __init sunzilog_ports_init(void)
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. */
if (sparc_cpu_model == sun4) {
NUM_SUNZILOG = 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,
* since Enterprise boxes might have SBUSes as well.
*/
central_node = prom_finddevice("/central");
if (central_node != 0 && central_node != -1)
node = prom_searchsiblings(prom_getchild(central_node), "fhc");
else
node = prom_searchsiblings(prom_getchild(prom_root_node), "sbus");
if (node != 0 && node != -1)
node = prom_getchild(node);
if (node == 0 || node == -1)
return -ENODEV;
if (sparc_cpu_model == sun4)
return 2;
node = prom_searchsiblings(node, "zs");
if (!node)
return -ENODEV;
scan.scanner = sunzilog_scan_count;
scan.depth = 0;
scan.devices = 0;
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;
sunzilog_scan(&scan, prom_getchild(prom_root_node));
NUM_SUNZILOG = 2;
}
return scan.devices;
}
static int __init sunzilog_init(void)
{
NUM_SUNZILOG = sunzilog_ports_count();
if (NUM_SUNZILOG == 0)
return -ENODEV;
sunzilog_alloc_tables();
......
......@@ -12,6 +12,7 @@
#define POLLRDBAND 128
#define POLLWRBAND 256
#define POLLMSG 512
#define POLLREMOVE 1024
struct pollfd {
int fd;
......
......@@ -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
*
* Hey Dave, that do not touch sign is too much of an incentive
* - Anton
* - Anton & Pete
*/
#define switch_to(prev, next, last) do { \
__label__ here; \
......@@ -160,6 +160,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
"wr %%g4, 0x20, %%psr\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" \
"wr %%g5, 0x0, %%wim\n\t" \
"ldd [%%sp + 0x00], %%l0\n\t" \
......
......@@ -207,7 +207,7 @@
#define __NR_uname 189 /* Linux Specific */
#define __NR_init_module 190 /* 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_lock 194 Linux Specific */
/* #define __NR_mpx 195 Linux Specific */
......
......@@ -98,8 +98,8 @@ struct sun4c_vac_props {
unsigned int num_bytes; /* Size of the cache */
unsigned int num_lines; /* Number of cache lines */
unsigned int do_hwflushes; /* Hardware flushing available? */
enum { NONE, WRITE_THROUGH,
WRITE_BACK } type; /* What type of VAC? */
enum { VAC_NONE, VAC_WRITE_THROUGH,
VAC_WRITE_BACK } type; /* What type of VAC? */
unsigned int linesize; /* Size of each line in bytes */
unsigned int log2lsize; /* log2(linesize) */
unsigned int on; /* VAC is enabled */
......
......@@ -12,6 +12,7 @@
#define POLLRDBAND 128
#define POLLWRBAND 256
#define POLLMSG 512
#define POLLREMOVE 1024
struct pollfd {
int fd;
......
......@@ -207,7 +207,7 @@
#define __NR_uname 189 /* Linux Specific */
#define __NR_init_module 190 /* 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_lock 194 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