Commit 67cecd1e authored by Linus Torvalds's avatar Linus Torvalds

Merge penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/s390

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 175ceea9 a8023367
......@@ -11,38 +11,6 @@ config SWAP
bool
default y
config ISA
bool
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
inside your box. Other bus systems are PCI, EISA, MicroChannel
(MCA) or VESA. ISA is an older system, now being displaced by PCI;
newer boards don't support it. If you have ISA, say Y, otherwise N.
config EISA
bool
---help---
The Extended Industry Standard Architecture (EISA) bus was
developed as an open alternative to the IBM MicroChannel bus.
The EISA bus provided some of the features of the IBM MicroChannel
bus while maintaining backward compatibility with cards made for
the older ISA bus. The EISA bus saw limited use between 1988 and
1995 when it was made obsolete by the PCI bus.
Say Y here if you are building a kernel for an EISA-based machine.
Otherwise, say N.
config MCA
bool
help
MicroChannel Architecture is found in some IBM PS/2 machines and
laptops. It is a bus system similar to PCI or ISA. See
<file:Documentation/mca.txt> (and especially the web page given
there) before attempting to build an MCA bus kernel.
config UID16
bool
default y
......@@ -57,7 +25,6 @@ config RWSEM_XCHGADD_ALGORITHM
config GENERIC_BUST_SPINLOCK
bool
mainmenu "Linux Kernel Configuration"
config ARCH_S390
......@@ -115,6 +82,13 @@ config NR_CPUS
int "Maximum number of CPUs (2-32)"
depends on SMP
default "32"
help
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 32 and the
minimum value which makes sense is 2.
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
comment "I/O subsystem configuration"
......@@ -153,6 +127,14 @@ comment "Misc"
config PREEMPT
bool "Preemptible Kernel"
help
This option reduces the latency of the kernel when reacting to
real-time or interactive events by allowing a low priority process to
be preempted even if it is in kernel mode executing a system call.
This allows applications to run more reliably even when the system is
under load.
Say N if you are unsure.
config IPL
bool "Builtin IPL record support"
......
......@@ -16,6 +16,7 @@
LDFLAGS := -m elf_s390
OBJCOPYFLAGS := -O binary
LDFLAGS_vmlinux := -e start
LDFLAGS_BLOB := --format binary --oformat elf32-s390
CFLAGS += -pipe -fno-strength-reduce
......@@ -28,18 +29,14 @@ libs-y += arch/s390/lib/
all: image listing
listing: vmlinux
@$(MAKEBOOT) listing
makeboot = $(call descend,arch/$(ARCH)/boot,$(1))
BOOTIMAGE= arch/$(ARCH)/boot/image
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
image: vmlinux
@$(MAKEBOOT) image
install: vmlinux
@$(MAKEBOOT) BOOTIMAGE=image install
listing install image: vmlinux
+@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) $@)
archclean:
+@$(call makeboot,clean)
archmrproper:
......
#
# arch/s390/boot/Makefile
# Makefile for the linux s390-specific parts of the memory manager.
#
EXTRA_AFLAGS := -traditional
include $(TOPDIR)/Rules.make
%.lnk: %.o
$(LD) $(LDFLAGS) -Ttext 0x0 -o $@ $<
quiet_cmd_listing = OBJDUMP $(echo_target)
cmd_listing = $(OBJDUMP) --disassemble --disassemble-all \
--disassemble-zeroes --reloc vmlinux > $@
%.boot: %.lnk
$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
$(obj)/image: vmlinux
$(call if_changed,objcopy)
image: $(TOPDIR)/vmlinux \
iplfba.boot ipleckd.boot ipldump.boot
$(OBJCOPY) $(OBJCOPYFLAGS) $(TOPDIR)/vmlinux image
$(NM) $(TOPDIR)/vmlinux | grep -v '\(compiled\)\|\( [aUw] \)\|\(\.\)\|\(LASH[RL]DI\)' | sort > $(TOPDIR)/System.map
$(obj)/listing: vmlinux
$(call if_changed,listing)
listing: ../../../vmlinux
$(OBJDUMP) --disassemble --disassemble-all --disassemble-zeroes --reloc $(TOPDIR)/vmlinux > listing
image: $(obj)/image
listing: $(obj)/listing
clean:
rm -f image listing iplfba.boot ipleckd.boot ipldump.boot
rm -f $(obj)/image $(obj)/listing
install: $(CONFIGURE) $(BOOTIMAGE)
sh -x ./install.sh $(KERNELRELEASE) $(BOOTIMAGE) $(TOPDIR)/System.map $(TOPDIR)/Kerntypes "$(INSTALL_PATH)"
sh -x $(obj)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map Kerntypes "$(INSTALL_PATH)"
#
# Automatically generated make config: don't edit
#
# CONFIG_ISA is not set
# CONFIG_EISA is not set
# CONFIG_MCA is not set
CONFIG_MMU=y
CONFIG_SWAP=y
CONFIG_UID16=y
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_GENERIC_BUST_SPINLOCK is not set
CONFIG_ARCH_S390=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_CONFIDENTIAL=y
#
# General setup
......@@ -27,7 +25,8 @@ CONFIG_SYSCTL=y
# Loadable module support
#
CONFIG_MODULES=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_UNLOAD is not set
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_KMOD=y
#
......@@ -39,13 +38,13 @@ CONFIG_KMOD=y
#
CONFIG_SMP=y
CONFIG_MATHEMU=y
CONFIG_NR_CPUS=64
CONFIG_NR_CPUS=32
#
# I/O subsystem configuration
#
CONFIG_MACHCHK_WARNING=y
CONFIG_QDIO=m
CONFIG_QDIO=y
# CONFIG_QDIO_PERF_STATS is not set
#
......@@ -57,7 +56,7 @@ CONFIG_IPL=y
CONFIG_IPL_VM=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_BINFMT_MISC=m
# CONFIG_PROCESS_DEBUG is not set
CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set
......@@ -65,79 +64,15 @@ CONFIG_PFAULT=y
#
# SCSI support
#
CONFIG_SCSI=m
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=m
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=m
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_SR_EXTRA_DEVS=10
CONFIG_CHR_DEV_SG=m
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_REPORT_LUNS is not set
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
#
# SCSI low-level drivers
#
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_DMA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
#
# PCMCIA SCSI adapter support
#
# CONFIG_SCSI_PCMCIA is not set
# CONFIG_SCSI is not set
#
# Block device drivers
#
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=24576
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
CONFIG_BLK_DEV_XPRAM=m
......@@ -147,66 +82,63 @@ CONFIG_BLK_DEV_XPRAM=m
CONFIG_DASD=y
CONFIG_DASD_ECKD=y
CONFIG_DASD_FBA=y
# CONFIG_DASD_DIAG is not set
CONFIG_DASD_DIAG=y
#
# Multi-device support (RAID and LVM)
#
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
# CONFIG_MD_LINEAR is not set
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
CONFIG_MD_RAID5=m
# CONFIG_MD_MULTIPATH is not set
# CONFIG_BLK_DEV_LVM is not set
CONFIG_MD_MULTIPATH=m
# CONFIG_BLK_DEV_DM is not set
#
# Character device drivers
#
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
CONFIG_UNIX98_PTY_COUNT=2048
#
# S/390 character device drivers
#
CONFIG_TN3270=y
CONFIG_TN3270_CONSOLE=y
# CONFIG_TN3270 is not set
CONFIG_TN3215=y
CONFIG_TN3215_CONSOLE=y
CONFIG_HWC=y
CONFIG_HWC_CONSOLE=y
CONFIG_HWC_CPI=m
CONFIG_SCLP=y
CONFIG_SCLP_TTY=y
CONFIG_SCLP_CONSOLE=y
CONFIG_SCLP_CPI=m
CONFIG_S390_TAPE=m
#
# S/390 tape interface support
#
CONFIG_S390_TAPE_CHAR=y
CONFIG_S390_TAPE_BLOCK=y
#
# S/390 tape hardware support
#
CONFIG_S390_TAPE_3490=m
CONFIG_S390_TAPE_3480=m
CONFIG_S390_TAPE_34XX=m
#
# Network device drivers
#
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
CONFIG_NET_ETHERNET=y
CONFIG_TR=y
# CONFIG_TR is not set
# CONFIG_FDDI is not set
#
# S/390 network device drivers
#
CONFIG_CHANDEV=y
CONFIG_HOTPLUG=y
CONFIG_LCS=m
CONFIG_CTC=m
......@@ -221,6 +153,7 @@ CONFIG_PACKET=y
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
......@@ -231,19 +164,19 @@ CONFIG_IP_MULTICAST=y
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_XFRM_USER is not set
CONFIG_IPV6=m
#
# SCTP Configuration (EXPERIMENTAL)
# SCTP Configuration (EXPERIMENTAL)
#
CONFIG_IPV6_SCTP__=m
CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_LLC is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DEV_APPLETALK is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
......@@ -257,66 +190,70 @@ CONFIG_NET_FASTROUTE=y
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CBQ=m
# CONFIG_NET_SCH_HTB is not set
CONFIG_NET_SCH_CSZ=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_POLICE=y
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
#
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
CONFIG_EXT3_FS=y
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_TMPFS is not set
CONFIG_RAMFS=y
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_ZISOFS is not set
# CONFIG_JFS_FS is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
CONFIG_DEVFS_FS=y
# CONFIG_DEVFS_MOUNT is not set
# CONFIG_DEVFS_DEBUG is not set
# CONFIG_DEVPTS_FS is not set
# CONFIG_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UDF_FS is not set
# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_XFS_FS is not set
# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
#
# Network File Systems
......@@ -324,25 +261,20 @@ CONFIG_EXT2_FS=y
# CONFIG_CODA_FS is not set
# CONFIG_INTERMEZZO_FS is not set
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
# CONFIG_ROOT_NFS is not set
CONFIG_NFS_V3=y
# CONFIG_NFS_V4 is not set
CONFIG_NFSD=y
# CONFIG_NFSD_V3 is not set
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
# CONFIG_CIFS is not set
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
# CONFIG_NCPFS_STRONG is not set
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
# CONFIG_ZISOFS_FS is not set
# CONFIG_AFS_FS is not set
#
# Partition Types
......@@ -360,8 +292,6 @@ CONFIG_IBM_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
#
# Kernel hacking
......@@ -373,9 +303,20 @@ CONFIG_MAGIC_SYSRQ=y
#
CONFIG_SECURITY_CAPABILITIES=y
#
# Cryptographic options
#
CONFIG_CRYPTO=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TEST is not set
#
# Library routines
#
# CONFIG_CRC32 is not set
# CONFIG_ZLIB_INFLATE is not set
# CONFIG_ZLIB_DEFLATE is not set
......@@ -10,7 +10,7 @@ obj-y := entry.o bitmap.o traps.o time.o process.o \
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
semaphore.o reipl.o s390_ext.o debug.o
obj-$(CONFIG_MODULES) += s390_ksyms.o
obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
obj-$(CONFIG_SMP) += smp.o
#
......
......@@ -474,10 +474,10 @@ sys_call_table:
.long sys_adjtimex
.long sys_mprotect /* 125 */
.long sys_sigprocmask
.long sys_create_module
.long sys_ni_syscall /* old "create module" */
.long sys_init_module
.long sys_delete_module
.long sys_get_kernel_syms /* 130 */
.long sys_ni_syscall /* 130: old get_kernel_syms */
.long sys_quotactl
.long sys_getpgid
.long sys_fchdir
......@@ -514,7 +514,7 @@ sys_call_table:
.long sys_setresuid16
.long sys_getresuid16 /* 165 */
.long sys_ni_syscall /* for vm86 */
.long sys_query_module
.long sys_ni_syscall /* old sys_query_module */
.long sys_poll
.long sys_nfsservctl
.long sys_setresgid16 /* 170 */
......@@ -596,7 +596,11 @@ sys_call_table:
.long sys_io_submit
.long sys_io_cancel
.long sys_exit_group
.rept 255-248
.long sys_epoll_create
.long sys_epoll_ctl /* 250 */
.long sys_epoll_wait
.long sys_set_tid_address
.rept 255-252
.long sys_ni_syscall
.endr
......
/*
* arch/s390x/kernel/module.c - Kernel module help for s390x.
*
* S390 version
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* based on i386 version
* Copyright (C) 2001 Rusty Russell.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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
*/
#include <linux/module.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#if 0
#define DEBUGP printk
#else
#define DEBUGP(fmt , ...)
#endif
void *module_alloc(unsigned long size)
{
if (size == 0)
return NULL;
return vmalloc(size);
}
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
/* FIXME: If module_region == mod->init_region, trim exception
table entries. */
}
/* s390/s390x needs additional memory for GOT/PLT sections. */
long module_core_size(const Elf32_Ehdr *hdr,
const Elf32_Shdr *sechdrs,
const char *secstrings,
struct module *module)
{
// FIXME: add space needed for GOT/PLT
return module->core_size;
}
long module_init_size(const Elf32_Ehdr *hdr,
const Elf32_Shdr *sechdrs,
const char *secstrings,
struct module *module)
{
return module->init_size;
}
int apply_relocate(Elf_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
unsigned int i;
ElfW(Rel) *rel = (void *)sechdrs[relsec].sh_offset;
ElfW(Sym) *sym;
ElfW(Addr) *location;
DEBUGP("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_offset
+ rel[i].r_offset;
/* This is the symbol it is referring to */
sym = (ElfW(Sym) *)sechdrs[symindex].sh_offset
+ ELFW(R_SYM)(rel[i].r_info);
if (!sym->st_value) {
printk(KERN_WARNING "%s: Unknown symbol %s\n",
me->name, strtab + sym->st_name);
return -ENOENT;
}
switch (ELF_R_TYPE(rel[i].r_info)) {
case R_390_8: /* Direct 8 bit. */
*(u8*) location += sym->st_value;
break;
case R_390_12: /* Direct 12 bit. */
*(u16*) location = (*(u16*) location & 0xf000) |
(sym->st_value & 0xfff);
break;
case R_390_16: /* Direct 16 bit. */
*(u16*) location += sym->st_value;
break;
case R_390_32: /* Direct 32 bit. */
*(u32*) location += sym->st_value;
break;
case R_390_PC16: /* PC relative 16 bit. */
*(u16*) location += sym->st_value
- (unsigned long )location;
case R_390_PC16DBL: /* PC relative 16 bit shifted by 1. */
*(u16*) location += (sym->st_value
- (unsigned long )location) >> 1;
case R_390_PC32: /* PC relative 32 bit. */
*(u32*) location += sym->st_value
- (unsigned long )location;
break;
case R_390_GOT12: /* 12 bit GOT offset. */
case R_390_GOT16: /* 16 bit GOT offset. */
case R_390_GOT32: /* 32 bit GOT offset. */
// FIXME: TODO
break;
case R_390_PLT16DBL: /* 16 bit PC rel. PLT shifted by 1. */
case R_390_PLT32: /* 32 bit PC relative PLT address. */
// FIXME: TODO
break;
case R_390_GLOB_DAT: /* Create GOT entry. */
case R_390_JMP_SLOT: /* Create PLT entry. */
*location = sym->st_value;
break;
case R_390_RELATIVE: /* Adjust by program base. */
// FIXME: TODO
break;
case R_390_GOTOFF: /* 32 bit offset to GOT. */
// FIXME: TODO
break;
case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
// FIXME: TODO
break;
default:
printk(KERN_ERR "module %s: Unknown relocation: %lu\n",
me->name,
(unsigned long)ELF_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return 0;
}
int apply_relocate_add(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
me->name);
return -ENOEXEC;
}
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
return 0;
}
......@@ -164,9 +164,9 @@ __setup("condev=", condev_setup);
static int __init conmode_setup(char *str)
{
#if defined(CONFIG_HWC_CONSOLE)
if (strncmp(str, "hwc", 4) == 0)
SET_CONSOLE_HWC;
#if defined(CONFIG_SCLP_CONSOLE)
if (strncmp(str, "hwc", 4) == 0 || strncmp(str, "sclp", 5) == 0)
SET_CONSOLE_SCLP;
#endif
#if defined(CONFIG_TN3215_CONSOLE)
if (strncmp(str, "3215", 5) == 0)
......@@ -198,8 +198,8 @@ static void __init conmode_default(void)
*/
cpcmd("TERM CONMODE 3215", NULL, 0);
if (ptr == NULL) {
#if defined(CONFIG_HWC_CONSOLE)
SET_CONSOLE_HWC;
#if defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
#endif
return;
}
......@@ -208,16 +208,16 @@ static void __init conmode_default(void)
SET_CONSOLE_3270;
#elif defined(CONFIG_TN3215_CONSOLE)
SET_CONSOLE_3215;
#elif defined(CONFIG_HWC_CONSOLE)
SET_CONSOLE_HWC;
#elif defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
#endif
} else if (strncmp(ptr + 8, "3215", 4) == 0) {
#if defined(CONFIG_TN3215_CONSOLE)
SET_CONSOLE_3215;
#elif defined(CONFIG_TN3270_CONSOLE)
SET_CONSOLE_3270;
#elif defined(CONFIG_HWC_CONSOLE)
SET_CONSOLE_HWC;
#elif defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
#endif
}
} else if (MACHINE_IS_P390) {
......@@ -227,8 +227,8 @@ static void __init conmode_default(void)
SET_CONSOLE_3270;
#endif
} else {
#if defined(CONFIG_HWC_CONSOLE)
SET_CONSOLE_HWC;
#if defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
#endif
}
}
......
......@@ -274,7 +274,7 @@ void machine_power_off_smp(void)
void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
{
int bits;
unsigned long bits;
/*
* handle bit signal external calls
......@@ -282,9 +282,7 @@ void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
* For the ec_schedule signal we have to do nothing. All the work
* is done automatically when we return from the interrupt.
*/
do {
bits = atomic_read(&S390_lowcore.ext_call_fast);
} while (atomic_compare_and_swap(bits,0,&S390_lowcore.ext_call_fast));
bits = xchg(&S390_lowcore.ext_call_fast, 0);
if (test_bit(ec_call_function, &bits))
do_call_function();
......@@ -296,13 +294,12 @@ void do_ext_call_interrupt(struct pt_regs *regs, __u16 code)
*/
static sigp_ccode smp_ext_bitcall(int cpu, ec_bit_sig sig)
{
struct _lowcore *lowcore = lowcore_ptr[cpu];
sigp_ccode ccode;
/*
* Set signaling bit in lowcore of target cpu and kick it
*/
atomic_set_mask(1<<sig, &lowcore->ext_call_fast);
set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
ccode = signal_processor(cpu, sigp_external_call);
return ccode;
}
......@@ -323,7 +320,7 @@ static void smp_ext_bitcall_others(ec_bit_sig sig)
/*
* Set signaling bit in lowcore of target cpu and kick it
*/
atomic_set_mask(1<<sig, &lowcore->ext_call_fast);
set_bit(sig, (unsigned long *) &lowcore_ptr[i]->ext_call_fast);
while (signal_processor(i, sigp_external_call) == sigp_busy)
udelay(10);
}
......
......@@ -140,7 +140,6 @@ static inline __u32 div64_32(__u64 dividend, __u32 divisor)
*/
static void do_comparator_interrupt(struct pt_regs *regs, __u16 error_code)
{
int cpu = smp_processor_id();
__u64 tmp;
__u32 ticks;
......
......@@ -72,8 +72,8 @@ extern char _stext, _etext;
#ifdef CONFIG_MODULES
extern struct module *module_list;
extern struct module kernel_module;
/* FIXME: Accessed without a lock --RR */
extern struct list_head modules;
static inline int kernel_text_address(unsigned long addr)
{
......@@ -84,11 +84,11 @@ static inline int kernel_text_address(unsigned long addr)
addr <= (unsigned long) &_etext)
return 1;
for (mod = module_list; mod != &kernel_module; mod = mod->next) {
list_for_each_entry(mod, &modules, list) {
/* mod_bound tests for addr being inside the vmalloc'ed
* module area. Of course it'd be better to test only
* for the .text subset... */
if (mod_bound(addr, 0, mod)) {
if (mod_bound((void*)addr, 0, mod)) {
retval = 1;
break;
}
......
/*
* arch/s390/lib/uaccess.S
* fixup routines for copy_{from|to}_user functions.
* __copy_{from|to}_user functions.
*
* s390
* Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* These functions have standard call interface
......@@ -22,17 +22,23 @@ __copy_from_user_asm:
1: sacf 0
lr %r2,%r5
br %r14
2: sll %r4,1
srl %r4,1
lhi %r3,-4096
sll %r3,1
srl %r3,1
n %r3,__LC_TRANS_EXC_ADDR
sr %r3,%r4
jm 1b
j 0b
2: lhi %r1,-4096
lr %r3,%r4
slr %r3,%r1 # %r3 = %r4 + 4096
nr %r3,%r1 # %r3 = (%r4 + 4096) & -4096
slr %r3,%r4 # %r3 = #bytes to next user page boundary
clr %r5,%r3 # copy crosses next page boundary ?
jnh 1b # no, this page fauled
# The page after the current user page might have faulted.
# We cant't find out which page because the program check handler
# might have callled schedule, destroying all lowcore information.
# We retry with the shortened length.
3: mvcle %r2,%r4,0
jo 3b
j 1b
.section __ex_table,"a"
.long 0b,2b
.long 3b,1b
.previous
.align 4
......@@ -46,17 +52,23 @@ __copy_to_user_asm:
1: sacf 0
lr %r2,%r3
br %r14
2: sll %r4,1
srl %r4,1
lhi %r5,-4096
sll %r5,1
srl %r5,1
n %r5,__LC_TRANS_EXC_ADDR
sr %r5,%r4
jm 1b
j 0b
2: lhi %r1,-4096
lr %r5,%r4
slr %r5,%r1 # %r5 = %r4 + 4096
nr %r5,%r1 # %r5 = (%r4 + 4096) & -4096
slr %r5,%r4 # %r5 = #bytes to next user page boundary
clr %r3,%r5 # copy crosses next page boundary ?
jnh 1b # no, the current page fauled
# The page after the current user page might have faulted.
# We cant't find out which page because the program check handler
# might have callled schedule, destroying all lowcore information.
# We retry with the shortened length.
3: mvcle %r4,%r2,0
jo 3b
j 1b
.section __ex_table,"a"
.long 0b,2b
.long 0b,2b
.long 3b,1b
.previous
.align 4
......@@ -71,18 +83,26 @@ __clear_user_asm:
0: mvcle %r4,%r2,0
jo 0b
1: sacf 0
lr %r2,%r3
br %r14
2: sll %r4,1
srl %r4,1
lhi %r5,-4096
sll %r5,1
srl %r5,1
n %r5,__LC_TRANS_EXC_ADDR
sr %r5,%r4
jm 1b
j 0b
2: lr %r2,%r5
lhi %r1,-4096
slr %r5,%r1 # %r5 = %r4 + 4096
nr %r5,%r1 # %r5 = (%r4 + 4096) & -4096
slr %r5,%r4 # %r5 = #bytes to next user page boundary
clr %r2,%r5 # copy crosses next page boundary ?
jnh 1b # no, the current page fauled
# The page after the current user page might have faulted.
# We cant't find out which page because the program check handler
# might have callled schedule, destroying all lowcore information.
# We retry with the shortened length.
slr %r2,%r5
3: mvcle %r4,%r2,0
jo 3b
j 1b
4: alr %r2,%r5
j 1b
.section __ex_table,"a"
.long 0b,2b
.long 0b,2b
.long 3b,4b
.previous
......@@ -42,6 +42,7 @@ extern spinlock_t modlist_lock;
unsigned long
search_exception_table(unsigned long addr)
{
struct list_head *i;
unsigned long ret = 0;
#ifndef CONFIG_MODULES
......@@ -52,16 +53,17 @@ search_exception_table(unsigned long addr)
return ret;
#else
unsigned long flags;
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
addr &= 0x7fffffff; /* remove amode bit from address */
/* The kernel is the last "module" -- no need to treat it special. */
spin_lock_irqsave(&modlist_lock, flags);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
list_for_each(i, &extables) {
struct exception_table *ex
= list_entry(i, struct exception_table, list);
if (ex->num_entries == 0)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
ret = search_one_table(ex->entry,
ex->entry + ex->num_entries - 1, addr);
if (ret) {
ret = ret | PSW_ADDR_AMODE31;
break;
......
......@@ -188,7 +188,7 @@ void free_initmem(void)
free_page(addr);
totalram_pages++;
}
printk ("Freeing unused kernel memory: %dk freed\n",
printk ("Freeing unused kernel memory: %ldk freed\n",
((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10);
}
......
......@@ -25,6 +25,7 @@ SECTIONS
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(64);
__start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
......@@ -40,18 +41,31 @@ SECTIONS
CONSTRUCTORS
}
. = ALIGN(4096);
__nosave_begin = .;
.data_nosave : { *(.data.nosave) }
. = ALIGN(4096);
__nosave_end = .;
. = ALIGN(4096);
.data.page_aligned : { *(.data.idt) }
. = ALIGN(32);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
_edata = .; /* End of data section */
. = ALIGN(8192); /* init_task */
.data.init_task : { *(.data.init_task) }
/* will be freed after init */
. = ALIGN(4096); /* Init code and data */
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
.init.text : { *(.init.text) }
.init.data : { *(.init.data) }
. = ALIGN(256);
__setup_start = .;
.setup.init : { *(.setup.init) }
.init.setup : { *(.init.setup) }
__setup_end = .;
__initcall_start = .;
.initcall.init : {
......@@ -65,23 +79,29 @@ SECTIONS
}
__initcall_end = .;
. = ALIGN(256);
__initramfs_start = .;
.init.ramfs : { *(.init.initramfs) }
__initramfs_end = .;
. = ALIGN(256);
__per_cpu_start = .;
.data.percpu : { *(.data.percpu) }
__per_cpu_end = .;
. = ALIGN(4096);
__init_end = .;
/* freed after init ends here */
. = ALIGN(32);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
__bss_start = .; /* BSS */
.bss : { *(.bss) }
__bss_stop = .;
. = ALIGN(4096);
.data.page_aligned : { *(.data.idt) }
_end = . ;
__bss_start = .; /* BSS */
.bss : {
*(.bss)
/* Sections to be discarded */
/DISCARD/ : {
*(.exit.text)
*(.exit.data)
*(.exitcall.exit)
}
_end = . ;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
......
......@@ -11,38 +11,6 @@ config SWAP
bool
default y
config ISA
bool
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
inside your box. Other bus systems are PCI, EISA, MicroChannel
(MCA) or VESA. ISA is an older system, now being displaced by PCI;
newer boards don't support it. If you have ISA, say Y, otherwise N.
config EISA
bool
---help---
The Extended Industry Standard Architecture (EISA) bus was
developed as an open alternative to the IBM MicroChannel bus.
The EISA bus provided some of the features of the IBM MicroChannel
bus while maintaining backward compatibility with cards made for
the older ISA bus. The EISA bus saw limited use between 1988 and
1995 when it was made obsolete by the PCI bus.
Say Y here if you are building a kernel for an EISA-based machine.
Otherwise, say N.
config MCA
bool
help
MicroChannel Architecture is found in some IBM PS/2 machines and
laptops. It is a bus system similar to PCI or ISA. See
<file:Documentation/mca.txt> (and especially the web page given
there) before attempting to build an MCA bus kernel.
config RWSEM_GENERIC_SPINLOCK
bool
......@@ -108,6 +76,13 @@ config NR_CPUS
int "Maximum number of CPUs (2-64)"
depends on SMP
default "64"
help
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 64 and the
minimum value which makes sense is 2.
This is purely to save memory - each supported CPU adds
approximately sixteen kilobytes to the kernel image.
config S390_SUPPORT
bool "Kernel support for 31 bit emulation"
......@@ -161,6 +136,14 @@ comment "Misc"
config PREEMPT
bool "Preemptible Kernel"
help
This option reduces the latency of the kernel when reacting to
real-time or interactive events by allowing a low priority process to
be preempted even if it is in kernel mode executing a system call.
This allows applications to run more reliably even when the system is
under load.
Say N if you are unsure.
config IPL
bool "Builtin IPL record support"
......
......@@ -16,7 +16,8 @@
LDFLAGS := -m elf64_s390
OBJCOPYFLAGS := -O binary
LDFLAGS_vmlinux := -e start
MODFLAGS += -fpic
MODFLAGS += -fpic -D__PIC__
LDFLAGS_BLOB := --format binary --oformat elf64-s390
CFLAGS += -pipe -fno-strength-reduce
......@@ -28,18 +29,14 @@ libs-y += arch/s390x/lib/
all: image listing
listing: vmlinux
@$(MAKEBOOT) listing
makeboot = $(call descend,arch/$(ARCH)/boot,$(1))
BOOTIMAGE= arch/$(ARCH)/boot/image
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
image: vmlinux
@$(MAKEBOOT) image
install: vmlinux
@$(MAKEBOOT) BOOTIMAGE=image install
listing install image: vmlinux
+@$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) $@)
archclean:
+@$(call makeboot,clean)
archmrproper:
......
......@@ -6,22 +6,22 @@ EXTRA_AFLAGS := -traditional
include $(TOPDIR)/Rules.make
%.lnk: %.o
$(LD) -Ttext 0x0 -o $@ $<
quiet_cmd_listing = OBJDUMP $(echo_target)
cmd_listing = $(OBJDUMP) --disassemble --disassemble-all \
--disassemble-zeroes --reloc vmlinux > $@
%.boot: %.lnk
$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
$(obj)/image: vmlinux
$(call if_changed,objcopy)
image: $(TOPDIR)/vmlinux \
iplfba.boot ipleckd.boot ipldump.boot
$(OBJCOPY) $(OBJCOPYFLAGS) $< $@
$(NM) $(TOPDIR)/vmlinux | grep -v '\(compiled\)\|\( [aUw] \)\|\(\.\)\|\(LASH[RL]DI\)' | sort > $(TOPDIR)/System.map
$(obj)/listing: vmlinux
$(call if_changed,listing)
listing: ../../../vmlinux
$(OBJDUMP) --disassemble --disassemble-all --disassemble-zeroes --reloc $(TOPDIR)/vmlinux > listing
image: $(obj)/image
listing: $(obj)/listing
clean:
rm -f image listing iplfba.boot ipleckd.boot ipldump.boot
rm -f $(obj)/image $(obj)/listing
install: $(CONFIGURE) $(BOOTIMAGE)
sh -x ./install.sh $(KERNELRELEASE) $(BOOTIMAGE) $(TOPDIR)/System.map $(TOPDIR)/Kerntypes "$(INSTALL_PATH)"
sh -x $(obj)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map Kerntypes "$(INSTALL_PATH)"
This diff is collapsed.
......@@ -12,7 +12,7 @@ obj-y := entry.o bitmap.o traps.o time.o process.o \
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
semaphore.o reipl.o s390_ext.o debug.o
obj-$(CONFIG_MODULES) += s390_ksyms.o
obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
obj-$(CONFIG_SMP) += smp.o
#
......
......@@ -503,10 +503,10 @@ sys_call_table:
.long SYSCALL(sys_adjtimex,sys32_adjtimex_wrapper)
.long SYSCALL(sys_mprotect,sys32_mprotect_wrapper) /* 125 */
.long SYSCALL(sys_sigprocmask,sys32_sigprocmask_wrapper)
.long SYSCALL(sys_create_module,sys32_create_module_wrapper)
.long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old "create module" */
.long SYSCALL(sys_init_module,sys32_init_module_wrapper)
.long SYSCALL(sys_delete_module,sys32_delete_module_wrapper)
.long SYSCALL(sys_get_kernel_syms,sys32_get_kernel_syms_wrapper) /* 130 */
.long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 130: old get_kernel_syms */
.long SYSCALL(sys_quotactl,sys32_quotactl_wrapper)
.long SYSCALL(sys_getpgid,sys32_getpgid_wrapper)
.long SYSCALL(sys_fchdir,sys32_fchdir_wrapper)
......@@ -543,7 +543,7 @@ sys_call_table:
.long SYSCALL(sys_ni_syscall,sys32_setresuid16_wrapper) /* old setresuid16 syscall */
.long SYSCALL(sys_ni_syscall,sys32_getresuid16_wrapper) /* old getresuid16 syscall */
.long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* for vm86 */
.long SYSCALL(sys_query_module,sys32_query_module_wrapper)
.long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old sys_query_module */
.long SYSCALL(sys_poll,sys32_poll_wrapper)
.long SYSCALL(sys_nfsservctl,sys32_nfsservctl_wrapper)
.long SYSCALL(sys_ni_syscall,sys32_setresgid16_wrapper) /* old setresgid16 syscall */
......@@ -625,7 +625,11 @@ sys_call_table:
.long SYSCALL(sys_io_submit,sys_ni_syscall)
.long SYSCALL(sys_io_cancel,sys_ni_syscall)
.long SYSCALL(sys_exit_group,sys32_exit_group_wrapper)
.rept 255-248
.long SYSCALL(sys_epoll_create,sys_ni_syscall)
.long SYSCALL(sys_epoll_ctl,sys_ni_syscall)
.long SYSCALL(sys_epoll_wait,sys_ni_syscall)
.long SYSCALL(sys_set_tid_address,sys_ni_syscall)
.rept 255-252
.long SYSCALL(sys_ni_syscall,sys_ni_syscall)
.endr
......
......@@ -1024,6 +1024,8 @@ int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
static void ioctl32_insert(struct ioctl32_list *entry)
{
int hash = ioctl32_hash(entry->handler.cmd);
entry->next = 0;
if (!ioctl32_hash_table[hash])
ioctl32_hash_table[hash] = entry;
else {
......@@ -1032,10 +1034,51 @@ static void ioctl32_insert(struct ioctl32_list *entry)
while (l->next)
l = l->next;
l->next = entry;
entry->next = 0;
}
}
int register_ioctl32_conversion(unsigned int cmd,
int (*handler)(unsigned int, unsigned int,
unsigned long, struct file *))
{
struct ioctl32_list *l, *new;
int hash;
hash = ioctl32_hash(cmd);
for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next)
if (l->handler.cmd == cmd)
return -EBUSY;
new = kmalloc(sizeof(struct ioctl32_list), GFP_KERNEL);
if (new == NULL)
return -ENOMEM;
new->handler.cmd = cmd;
new->handler.function = (void *) handler;
ioctl32_insert(new);
return 0;
}
int unregister_ioctl32_conversion(unsigned int cmd)
{
struct ioctl32_list *p, *l;
int hash;
hash = ioctl32_hash(cmd);
p = NULL;
for (l = ioctl32_hash_table[hash]; l != NULL; l = l->next) {
if (l->handler.cmd == cmd)
break;
p = l;
}
if (l == NULL)
return -ENOENT;
if (p == NULL)
ioctl32_hash_table[hash] = l->next;
else
p->next = l->next;
kfree(l);
return 0;
}
static int __init init_ioctl32(void)
{
int i;
......
This diff is collapsed.
/*
* arch/s390x/kernel/module.c - Kernel module help for s390x.
*
* S390 version
* Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* based on i386 version
* Copyright (C) 2001 Rusty Russell.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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
*/
#include <linux/module.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#if 0
#define DEBUGP printk
#else
#define DEBUGP(fmt , ...)
#endif
void *module_alloc(unsigned long size)
{
if (size == 0)
return NULL;
return vmalloc(size);
}
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
/* FIXME: If module_region == mod->init_region, trim exception
table entries. */
}
/* s390/s390x needs additional memory for GOT/PLT sections. */
long module_core_size(const Elf32_Ehdr *hdr,
const Elf32_Shdr *sechdrs,
const char *secstrings,
struct module *module)
{
// FIXME: add space needed for GOT/PLT
return module->core_size;
}
long module_init_size(const Elf32_Ehdr *hdr,
const Elf32_Shdr *sechdrs,
const char *secstrings,
struct module *module)
{
return module->init_size;
}
int apply_relocate(Elf_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
unsigned int i;
ElfW(Rel) *rel = (void *)sechdrs[relsec].sh_offset;
ElfW(Sym) *sym;
ElfW(Addr) *location;
DEBUGP("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_offset
+ rel[i].r_offset;
/* This is the symbol it is referring to */
sym = (ElfW(Sym) *)sechdrs[symindex].sh_offset
+ ELFW(R_SYM)(rel[i].r_info);
if (!sym->st_value) {
printk(KERN_WARNING "%s: Unknown symbol %s\n",
me->name, strtab + sym->st_name);
return -ENOENT;
}
switch (ELF_R_TYPE(rel[i].r_info)) {
case R_390_8: /* Direct 8 bit. */
*(u8*) location += sym->st_value;
break;
case R_390_12: /* Direct 12 bit. */
*(u16*) location = (*(u16*) location & 0xf000) |
(sym->st_value & 0xfff);
break;
case R_390_16: /* Direct 16 bit. */
*(u16*) location += sym->st_value;
break;
case R_390_32: /* Direct 32 bit. */
*(u32*) location += sym->st_value;
break;
case R_390_64: /* Direct 64 bit. */
*(u64*) location += sym->st_value;
break;
case R_390_PC16: /* PC relative 16 bit. */
*(u16*) location += sym->st_value
- (unsigned long )location;
case R_390_PC16DBL: /* PC relative 16 bit shifted by 1. */
*(u16*) location += (sym->st_value
- (unsigned long )location) >> 1;
case R_390_PC32: /* PC relative 32 bit. */
*(u32*) location += sym->st_value
- (unsigned long )location;
break;
case R_390_PC32DBL: /* PC relative 32 bit shifted by 1. */
*(u32*) location += (sym->st_value
- (unsigned long )location) >> 1;
break;
case R_390_PC64: /* PC relative 64 bit. */
*(u64*) location += sym->st_value
- (unsigned long )location;
break;
case R_390_GOT12: /* 12 bit GOT offset. */
case R_390_GOT16: /* 16 bit GOT offset. */
case R_390_GOT32: /* 32 bit GOT offset. */
case R_390_GOT64: /* 64 bit GOT offset. */
case R_390_GOTENT: /* 32 bit PC rel. to GOT entry >> 1. */
// FIXME: TODO
break;
case R_390_PLT16DBL: /* 16 bit PC rel. PLT shifted by 1. */
case R_390_PLT32: /* 32 bit PC relative PLT address. */
case R_390_PLT32DBL: /* 32 bit PC rel. PLT shifted by 1. */
case R_390_PLT64: /* 64 bit PC relative PLT address. */
// FIXME: TODO
break;
case R_390_GLOB_DAT: /* Create GOT entry. */
case R_390_JMP_SLOT: /* Create PLT entry. */
*location = sym->st_value;
break;
case R_390_RELATIVE: /* Adjust by program base. */
// FIXME: TODO
break;
case R_390_GOTOFF: /* 32 bit offset to GOT. */
// FIXME: TODO
break;
case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
case R_390_GOTPCDBL: /* 32 bit PC rel. GOT shifted by 1. */
// FIXME: TODO
break;
default:
printk(KERN_ERR "module %s: Unknown relocation: %lu\n",
me->name,
(unsigned long)ELF_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return 0;
}
int apply_relocate_add(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
me->name);
return -ENOEXEC;
}
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
return 0;
}
......@@ -60,6 +60,20 @@ EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(overflowuid);
EXPORT_SYMBOL(overflowgid);
#ifdef CONFIG_S390_SUPPORT
/*
* Dynamically add/remove 31 bit ioctl conversion functions.
*/
extern int register_ioctl32_conversion(unsigned int cmd,
int (*handler)(unsigned int,
unsigned int,
unsigned long,
struct file *));
int unregister_ioctl32_conversion(unsigned int cmd);
EXPORT_SYMBOL(register_ioctl32_conversion);
EXPORT_SYMBOL(unregister_ioctl32_conversion);
#endif
/*
* misc.
*/
......
......@@ -164,9 +164,9 @@ __setup("condev=", condev_setup);
static int __init conmode_setup(char *str)
{
#if defined(CONFIG_HWC_CONSOLE)
if (strncmp(str, "hwc", 4) == 0)
SET_CONSOLE_HWC;
#if defined(CONFIG_SCLP_CONSOLE)
if (strncmp(str, "hwc", 4) == 0 || strncmp(str, "sclp", 5) == 0)
SET_CONSOLE_SCLP;
#endif
#if defined(CONFIG_TN3215_CONSOLE)
if (strncmp(str, "3215", 5) == 0)
......@@ -198,8 +198,8 @@ static void __init conmode_default(void)
*/
cpcmd("TERM CONMODE 3215", NULL, 0);
if (ptr == NULL) {
#if defined(CONFIG_HWC_CONSOLE)
SET_CONSOLE_HWC;
#if defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
#endif
return;
}
......@@ -208,16 +208,16 @@ static void __init conmode_default(void)
SET_CONSOLE_3270;
#elif defined(CONFIG_TN3215_CONSOLE)
SET_CONSOLE_3215;
#elif defined(CONFIG_HWC_CONSOLE)
SET_CONSOLE_HWC;
#elif defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
#endif
} else if (strncmp(ptr + 8, "3215", 4) == 0) {
#if defined(CONFIG_TN3215_CONSOLE)
SET_CONSOLE_3215;
#elif defined(CONFIG_TN3270_CONSOLE)
SET_CONSOLE_3270;
#elif defined(CONFIG_HWC_CONSOLE)
SET_CONSOLE_HWC;
#elif defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
#endif
}
} else if (MACHINE_IS_P390) {
......@@ -227,8 +227,8 @@ static void __init conmode_default(void)
SET_CONSOLE_3270;
#endif
} else {
#if defined(CONFIG_HWC_CONSOLE)
SET_CONSOLE_HWC;
#if defined(CONFIG_SCLP_CONSOLE)
SET_CONSOLE_SCLP;
#endif
}
}
......
......@@ -126,7 +126,6 @@ void do_settimeofday(struct timeval *tv)
*/
static void do_comparator_interrupt(struct pt_regs *regs, __u16 error_code)
{
int cpu = smp_processor_id();
__u64 tmp;
__u32 ticks;
......
......@@ -74,8 +74,8 @@ extern char _stext, _etext;
#ifdef CONFIG_MODULES
extern struct module *module_list;
extern struct module kernel_module;
/* FIXME: Accessed without a lock --RR */
extern struct list_head modules;
static inline int kernel_text_address(unsigned long addr)
{
......@@ -86,11 +86,11 @@ static inline int kernel_text_address(unsigned long addr)
addr <= (unsigned long) &_etext)
return 1;
for (mod = module_list; mod != &kernel_module; mod = mod->next) {
list_for_each_entry(mod, &modules, list) {
/* mod_bound tests for addr being inside the vmalloc'ed
* module area. Of course it'd be better to test only
* for the .text subset... */
if (mod_bound(addr, 0, mod)) {
if (mod_bound((void*)addr, 0, mod)) {
retval = 1;
break;
}
......
......@@ -17,14 +17,14 @@ sys32_read_wrapper:
llgfr %r2,%r2 # unsigned int
llgtr %r3,%r3 # char *
llgfr %r4,%r4 # size_t
jg sys_read # branch to sys_read
jg sys32_read # branch to sys_read
.globl sys32_write_wrapper
sys32_write_wrapper:
llgfr %r2,%r2 # unsigned int
llgtr %r3,%r3 # const char *
llgfr %r4,%r4 # size_t
jg sys_write # branch to system call
jg sys32_write # branch to system call
.globl sys32_open_wrapper
sys32_open_wrapper:
......@@ -564,12 +564,6 @@ sys32_sigprocmask_wrapper:
llgtr %r4,%r4 # old_sigset_emu31 *
jg sys32_sigprocmask # branch to system call
.globl sys32_create_module_wrapper
sys32_create_module_wrapper:
llgtr %r2,%r2 # const char *
llgfr %r3,%r3 # size_t
jg sys32_create_module # branch to system call
.globl sys32_init_module_wrapper
sys32_init_module_wrapper:
llgtr %r2,%r2 # const char *
......@@ -581,11 +575,6 @@ sys32_delete_module_wrapper:
llgtr %r2,%r2 # const char *
jg sys32_delete_module # branch to system call
.globl sys32_get_kernel_syms_wrapper
sys32_get_kernel_syms_wrapper:
llgtr %r2,%r2 # struct kernel_sym_emu31 *
jg sys32_get_kernel_syms # branch to system call
.globl sys32_quotactl_wrapper
sys32_quotactl_wrapper:
lgfr %r2,%r2 # int
......@@ -786,15 +775,6 @@ sys32_getresuid16_wrapper:
llgtr %r4,%r4 # __kernel_old_uid_emu31_t *
jg sys32_getresuid16 # branch to system call
.globl sys32_query_module_wrapper
sys32_query_module_wrapper:
llgtr %r2,%r2 # const char *
lgfr %r3,%r3 # int
llgtr %r4,%r4 # char *
llgfr %r5,%r5 # size_t
llgtr %r6,%r6 # size_t *
jg sys32_query_module # branch to system call
.globl sys32_poll_wrapper
sys32_poll_wrapper:
llgtr %r2,%r2 # struct pollfd *
......
/*
* arch/s390x/lib/uaccess.S
* fixup routines for copy_{from|to}_user functions.
* __copy_{from|to}_user functions.
*
* S390
* Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
* s390
* Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* These functions have standard call interface
......@@ -22,14 +22,23 @@ __copy_from_user_asm:
1: sacf 0
lgr %r2,%r5
br %r14
2: lghi %r3,-4096
ng %r3,__LC_TRANS_EXC_ADDR
sgr %r3,%r4
jm 1b
j 0b
2: lghi %r1,-4096
lgr %r3,%r4
slgr %r3,%r1 # %r3 = %r4 + 4096
ngr %r3,%r1 # %r3 = (%r4 + 4096) & -4096
slgr %r3,%r4 # %r3 = #bytes to next user page boundary
clgr %r5,%r3 # copy crosses next page boundary ?
jnh 1b # no, this page fauled
# The page after the current user page might have faulted.
# We cant't find out which page because the program check handler
# might have callled schedule, destroying all lowcore information.
# We retry with the shortened length.
3: mvcle %r2,%r4,0
jo 3b
j 1b
.section __ex_table,"a"
.align 8
.quad 0b,2b
.quad 3b,1b
.previous
.align 4
......@@ -43,14 +52,23 @@ __copy_to_user_asm:
1: sacf 0
lgr %r2,%r3
br %r14
2: lghi %r5,-4096
ng %r5,__LC_TRANS_EXC_ADDR
sgr %r5,%r4
jm 1b
j 0b
2: lghi %r1,-4096
lgr %r5,%r4
slgr %r5,%r1 # %r5 = %r4 + 4096
ngr %r5,%r1 # %r5 = (%r4 + 4096) & -4096
slgr %r5,%r4 # %r5 = #bytes to next user page boundary
clgr %r3,%r5 # copy crosses next page boundary ?
jnh 1b # no, the current page fauled
# The page after the current user page might have faulted.
# We cant't find out which page because the program check handler
# might have callled schedule, destroying all lowcore information.
# We retry with the shortened length.
3: mvcle %r4,%r2,0
jo 3b
j 1b
.section __ex_table,"a"
.align 8
.quad 0b,2b
.quad 0b,2b
.quad 3b,1b
.previous
.align 4
......@@ -65,14 +83,25 @@ __clear_user_asm:
0: mvcle %r4,%r2,0
jo 0b
1: sacf 0
lgr %r2,%r5
br %r14
2: lghi %r5,-4096
ng %r5,__LC_TRANS_EXC_ADDR
sgr %r5,%r4
jm 1b
j 0b
2: lgr %r2,%r5
lghi %r1,-4096
slgr %r5,%r1 # %r5 = %r4 + 4096
ngr %r5,%r1 # %r5 = (%r4 + 4096) & -4096
slgr %r5,%r4 # %r5 = #bytes to next user page boundary
clgr %r2,%r5 # copy crosses next page boundary ?
jnh 1b # no, the current page fauled
# The page after the current user page might have faulted.
# We cant't find out which page because the program check handler
# might have callled schedule, destroying all lowcore information.
# We retry with the shortened length.
slgr %r2,%r5
3: mvcle %r4,%r2,0
jo 3b
j 1b
4: algr %r2,%r5
j 1b
.section __ex_table,"a"
.align 8
.quad 0b,2b
.quad 0b,2b
.quad 3b,4b
.previous
......@@ -2,10 +2,8 @@
* arch/s390/mm/extable.c
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Hartmut Penner (hp@de.ibm.com)
*
* Derived from "arch/i386/mm/extable.c"
* identical to arch/i386/mm/extable.c
*/
#include <linux/config.h>
......@@ -42,24 +40,27 @@ extern spinlock_t modlist_lock;
unsigned long
search_exception_table(unsigned long addr)
{
struct list_head *i;
unsigned long ret = 0;
#ifndef CONFIG_MODULES
/* There is only the kernel to search. */
ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
return ret;
#else
unsigned long flags;
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
struct list_head *i;
/* The kernel is the last "module" -- no need to treat it special. */
spin_lock_irqsave(&modlist_lock, flags);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
list_for_each(i, &extables) {
struct exception_table *ex
= list_entry(i, struct exception_table, list);
if (ex->num_entries == 0)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
if (ret)
ret = search_one_table(ex->entry,
ex->entry + ex->num_entries - 1, addr);
if (ret)
break;
}
spin_unlock_irqrestore(&modlist_lock, flags);
......
/* ld script to make s390 Linux kernel
/*
* Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
*/
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
......@@ -25,6 +25,7 @@ SECTIONS
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
. = ALIGN(64);
__start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
......@@ -40,18 +41,31 @@ SECTIONS
CONSTRUCTORS
}
. = ALIGN(4096);
__nosave_begin = .;
.data_nosave : { *(.data.nosave) }
. = ALIGN(4096);
__nosave_end = .;
. = ALIGN(4096);
.data.page_aligned : { *(.data.idt) }
. = ALIGN(32);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
_edata = .; /* End of data section */
. = ALIGN(16384); /* init_task */
. = ALIGN(8192); /* init_task */
.data.init_task : { *(.data.init_task) }
/* will be freed after init */
. = ALIGN(4096); /* Init code and data */
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
.init.text : { *(.init.text) }
.init.data : { *(.init.data) }
. = ALIGN(256);
__setup_start = .;
.setup.init : { *(.setup.init) }
.init.setup : { *(.init.setup) }
__setup_end = .;
__initcall_start = .;
.initcall.init : {
......@@ -65,24 +79,29 @@ SECTIONS
}
__initcall_end = .;
. = ALIGN(256);
__initramfs_start = .;
.init.ramfs : { *(.init.initramfs) }
__initramfs_end = .;
. = ALIGN(256);
__per_cpu_start = .;
.data.percpu : { *(.data.percpu) }
__per_cpu_end = .;
. = ALIGN(4096);
__init_end = .;
/* freed after init ends here */
. = ALIGN(32);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
. = ALIGN(4096);
.data.page_aligned : { *(.data.idt) }
__bss_start = .; /* BSS */
.bss : { *(.bss) }
__bss_stop = .;
_end = . ;
__bss_start = .; /* BSS */
.bss : {
*(.bss)
/* Sections to be discarded */
/DISCARD/ : {
*(.exit.text)
*(.exit.data)
*(.exitcall.exit)
}
_end = . ;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
......
......@@ -146,10 +146,9 @@ extern long serial167_console_init(void);
extern void console_8xx_init(void);
extern int rs_8xx_init(void);
extern void mac_scc_console_init(void);
extern void hwc_console_init(void);
extern void hwc_tty_init(void);
extern void sclp_console_init(void);
extern void sclp_tty_init(void);
extern void con3215_init(void);
extern void tty3215_init(void);
extern void tub3270_con_init(void);
extern void tub3270_init(void);
extern void uart_console_init(void);
......@@ -2208,8 +2207,8 @@ void __init console_init(void)
#ifdef CONFIG_TN3215
con3215_init();
#endif
#ifdef CONFIG_HWC
hwc_console_init();
#ifdef CONFIG_SCLP_CONSOLE
sclp_console_init();
#endif
#ifdef CONFIG_STDIO_CONSOLE
stdio_console_init();
......@@ -2349,8 +2348,8 @@ void __init tty_init(void)
#ifdef CONFIG_TN3215
tty3215_init();
#endif
#ifdef CONFIG_HWC
hwc_tty_init();
#ifdef CONFIG_SCLP
sclp_tty_init();
#endif
#ifdef CONFIG_A2232
a2232board_init();
......
......@@ -257,24 +257,30 @@ config TN3215_CONSOLE
Include support for using an IBM 3215 line-mode terminal as a
Linux system console.
config HWC
bool "Support for HWC line mode terminal"
config SCLP
bool "Support for SCLP"
help
Include support for IBM HWC line-mode terminals.
Include support for the SCLP interface to the service element.
config HWC_CONSOLE
bool "console on HWC line mode terminal"
depends on HWC
config SCLP_TTY
bool "Support for SCLP line mode terminal"
depends on SCLP
help
Include support for IBM SCLP line-mode terminals.
config SCLP_CONSOLE
bool "Support for console on SCLP line mode terminal"
depends on SCLP_TTY
help
Include support for using an IBM HWC line-mode terminal as the Linux
system console.
config HWC_CPI
config SCLP_CPI
tristate "Control-Program Identification"
depends on HWC
depends on SCLP
help
This option enables the hardware console interface for system
identification This is commonly used for workload management and
identification. This is commonly used for workload management and
gives you a nice name for the system on the service element.
Please select this option as a module since built-in operation is
completely untested.
......
......@@ -11,9 +11,9 @@ dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \
dasd_genhd.o dasd_erp.o
obj-$(CONFIG_DASD) += dasd_mod.o
obj-$(CONFIG_DASD_DIAG) += dasd_diag_mod.o
obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o
obj-$(CONFIG_DASD_FBA) += dasd_fba_mod.o
obj-$(CONFIG_DASD_DIAG) += dasd_diag_mod.o
obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o
include $(TOPDIR)/Rules.make
......@@ -325,7 +325,6 @@ static int xpram_ioctl (struct inode *inode, struct file *filp,
{
struct hd_geometry *geo;
unsigned long size;
int idx = minor(inode->i_rdev);
if (cmd != HDIO_GETGEO)
return -EINVAL;
/*
......@@ -474,6 +473,7 @@ static int __init xpram_setup_blkdev(void)
out:
while (i--)
put_disk(xpram_disks[i]);
return rc;
}
/*
......
......@@ -2,28 +2,23 @@
# S/390 character devices
#
export-objs := hwc_rw.o tape.o tape34xx.o
export-objs := sclp_rw.o tape_core.o tape_devmap.o tape_std.o
tub3270-objs := tuball.o tubfs.o tubtty.o \
tubttyaid.o tubttybld.o tubttyscl.o \
tubttyrcl.o tubttysiz.o
tape390-$(CONFIG_S390_TAPE_CHAR) += tapechar.o
tape390-$(CONFIG_S390_TAPE_BLOCK) += tapeblock.o
tape390-objs := tape.o tape34xx.o $(sort $(tape390-y))
tape_3480_mod-objs := tape3480.o
tape_3490_mod-objs := tape3490.o
obj-y += ctrlchar.o
obj-$(CONFIG_TN3215) += con3215.o
obj-$(CONFIG_HWC) += hwc_con.o hwc_rw.o hwc_tty.o
obj-$(CONFIG_HWC_CPI) += hwc_cpi.o
obj-$(CONFIG_SCLP) += sclp.o
obj-$(CONFIG_SCLP_TTY) += sclp_rw.o sclp_tty.o
obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o
obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
obj-$(CONFIG_TN3270) += tub3270.o
obj-$(CONFIG_S390_TAPE) += tape390.o
obj-$(CONFIG_S390_TAPE_3480) += tape_3480_mod.o
obj-$(CONFIG_S390_TAPE_3490) += tape_3490_mod.o
tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o
tape-$(CONFIG_PROC_FS) += tape_proc.o
tape-objs := tape_core.o tape_std.o tape_char.o $(tape-y)
obj-$(CONFIG_S390_TAPE) += tape.o
obj-$(CONFIG_S390_TAPE_34XX) += tape_34xx.o
include $(TOPDIR)/Rules.make
/*
* drivers/s390/char/hwc.h
*
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
*
*
*
*/
#ifndef __HWC_H__
#define __HWC_H__
#define HWC_EXT_INT_PARAM_ADDR 0xFFFFFFF8
#define HWC_EXT_INT_PARAM_PEND 0x00000001
#define ET_OpCmd 0x01
#define ET_Msg 0x02
#define ET_StateChange 0x08
#define ET_PMsgCmd 0x09
#define ET_CntlProgOpCmd 0x20
#define ET_CntlProgIdent 0x0B
#define ET_SigQuiesce 0x1D
#define ET_OpCmd_Mask 0x80000000
#define ET_Msg_Mask 0x40000000
#define ET_StateChange_Mask 0x01000000
#define ET_PMsgCmd_Mask 0x00800000
#define ET_CtlProgOpCmd_Mask 0x00000001
#define ET_CtlProgIdent_Mask 0x00200000
#define ET_SigQuiesce_Mask 0x00000008
#define GMF_DOM 0x8000
#define GMF_SndAlrm 0x4000
#define GMF_HoldMsg 0x2000
#define LTF_CntlText 0x8000
#define LTF_LabelText 0x4000
#define LTF_DataText 0x2000
#define LTF_EndText 0x1000
#define LTF_PromptText 0x0800
#define HWC_COMMAND_INITIATED 0
#define HWC_BUSY 2
#define HWC_NOT_OPERATIONAL 3
#define hwc_cmdw_t u32;
#define HWC_CMDW_READDATA 0x00770005
#define HWC_CMDW_WRITEDATA 0x00760005
#define HWC_CMDW_WRITEMASK 0x00780005
#define GDS_ID_MDSMU 0x1310
#define GDS_ID_MDSRouteInfo 0x1311
#define GDS_ID_AgUnWrkCorr 0x1549
#define GDS_ID_SNACondReport 0x1532
#define GDS_ID_CPMSU 0x1212
#define GDS_ID_RoutTargInstr 0x154D
#define GDS_ID_OpReq 0x8070
#define GDS_ID_TextCmd 0x1320
#define GDS_KEY_SelfDefTextMsg 0x31
#define _HWCB_HEADER u16 length; \
u8 function_code; \
u8 control_mask[3]; \
u16 response_code;
#define _EBUF_HEADER u16 length; \
u8 type; \
u8 flags; \
u16 _reserved;
typedef struct {
_EBUF_HEADER
} __attribute__ ((packed))
evbuf_t;
#define _MDB_HEADER u16 length; \
u16 type; \
u32 tag; \
u32 revision_code;
#define _GO_HEADER u16 length; \
u16 type; \
u32 domid; \
u8 hhmmss_time[8]; \
u8 th_time[3]; \
u8 _reserved_0; \
u8 dddyyyy_date[7]; \
u8 _reserved_1; \
u16 general_msg_flags; \
u8 _reserved_2[10]; \
u8 originating_system_name[8]; \
u8 job_guest_name[8];
#define _MTO_HEADER u16 length; \
u16 type; \
u16 line_type_flags; \
u8 alarm_control; \
u8 _reserved[3];
typedef struct {
_GO_HEADER
} __attribute__ ((packed))
go_t;
typedef struct {
go_t go;
} __attribute__ ((packed))
mdb_body_t;
typedef struct {
_MDB_HEADER
mdb_body_t mdb_body;
} __attribute__ ((packed))
mdb_t;
typedef struct {
_EBUF_HEADER
mdb_t mdb;
} __attribute__ ((packed))
msgbuf_t;
typedef struct {
_HWCB_HEADER
msgbuf_t msgbuf;
} __attribute__ ((packed))
write_hwcb_t;
typedef struct {
_MTO_HEADER
} __attribute__ ((packed))
mto_t;
/* FIXME: don't define static variables in a header!!! */
#warning
static write_hwcb_t write_hwcb_template =
{
sizeof (write_hwcb_t),
0x00,
{
0x00,
0x00,
0x00
},
0x0000,
{
sizeof (msgbuf_t),
ET_Msg,
0x00,
0x0000,
{
sizeof (mdb_t),
0x0001,
0xD4C4C240,
0x00000001,
{
{
sizeof (go_t),
0x0001
}
}
}
}
};
#warning
static mto_t mto_template =
{
sizeof (mto_t),
0x0004,
LTF_EndText,
0x00
};
typedef u32 _hwcb_mask_t;
typedef struct {
_HWCB_HEADER
u16 _reserved;
u16 mask_length;
_hwcb_mask_t cp_receive_mask;
_hwcb_mask_t cp_send_mask;
_hwcb_mask_t hwc_receive_mask;
_hwcb_mask_t hwc_send_mask;
} __attribute__ ((packed))
init_hwcb_t;
#warning
static init_hwcb_t init_hwcb_template =
{
sizeof (init_hwcb_t),
0x00,
{
0x00,
0x00,
0x00
},
0x0000,
0x0000,
sizeof (_hwcb_mask_t),
ET_OpCmd_Mask | ET_PMsgCmd_Mask |
ET_StateChange_Mask | ET_SigQuiesce_Mask,
ET_Msg_Mask | ET_PMsgCmd_Mask | ET_CtlProgIdent_Mask
};
typedef struct {
_EBUF_HEADER
u8 validity_hwc_active_facility_mask:1;
u8 validity_hwc_receive_mask:1;
u8 validity_hwc_send_mask:1;
u8 validity_read_data_function_mask:1;
u16 _zeros:12;
u16 mask_length;
u64 hwc_active_facility_mask;
_hwcb_mask_t hwc_receive_mask;
_hwcb_mask_t hwc_send_mask;
u32 read_data_function_mask;
} __attribute__ ((packed))
statechangebuf_t;
#define _GDS_VECTOR_HEADER u16 length; \
u16 gds_id;
#define _GDS_SUBVECTOR_HEADER u8 length; \
u8 key;
typedef struct {
_GDS_VECTOR_HEADER
} __attribute__ ((packed))
gds_vector_t;
typedef struct {
_GDS_SUBVECTOR_HEADER
} __attribute__ ((packed))
gds_subvector_t;
typedef struct {
_HWCB_HEADER
} __attribute__ ((packed))
read_hwcb_t;
#warning
static read_hwcb_t read_hwcb_template =
{
PAGE_SIZE,
0x00,
{
0x00,
0x00,
0x80
}
};
#endif /* __HWC_H__ */
/*
* drivers/s390/char/hwc_con.c
* HWC line mode console driver
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/kdev_t.h>
#include <linux/string.h>
#include <linux/console.h>
#include <linux/fs.h>
#include <linux/init.h>
#include "hwc_rw.h"
#ifdef CONFIG_HWC_CONSOLE
#define hwc_console_major 4
#define hwc_console_minor 64
#define hwc_console_name "console"
void hwc_console_write (struct console *, const char *, unsigned int);
kdev_t hwc_console_device (struct console *);
void hwc_console_unblank (void);
#define HWC_CON_PRINT_HEADER "hwc console driver: "
struct console hwc_console =
{
.name = hwc_console_name,
.write = hwc_console_write,
.device = hwc_console_device,
.unblank = hwc_console_unblank,
.flags = CON_PRINTBUFFER,
};
void
hwc_console_write (
struct console *console,
const char *message,
unsigned int count)
{
if (kdev_val (console->device (console)) !=
kdev_val (hwc_console.device (&hwc_console))) {
hwc_printk (KERN_WARNING HWC_CON_PRINT_HEADER
"hwc_console_write() called with wrong "
"device number");
return;
}
hwc_write (0, message, count);
}
kdev_t
hwc_console_device (struct console * c)
{
return mk_kdev (hwc_console_major, hwc_console_minor);
}
void
hwc_console_unblank (void)
{
hwc_unblank ();
}
#endif
void __init
hwc_console_init (void)
{
if (!MACHINE_HAS_HWC)
return;
if (hwc_init () == 0) {
#ifdef CONFIG_HWC_CONSOLE
if (CONSOLE_IS_HWC)
register_console (&hwc_console);
#endif
} else
panic (HWC_CON_PRINT_HEADER "hwc initialisation failed !");
return;
}
/*
* Author: Martin Peschke <mpeschke@de.ibm.com>
* Copyright (C) 2001 IBM Entwicklung GmbH, IBM Corporation
*/
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/sched.h>
#include <asm/semaphore.h>
#include <asm/ebcdic.h>
#include "hwc_rw.h"
#include "hwc.h"
#define CPI_RETRIES 3
#define CPI_SLEEP_TICKS 50
#define CPI_LENGTH_SYSTEM_TYPE 8
#define CPI_LENGTH_SYSTEM_NAME 8
#define CPI_LENGTH_SYSPLEX_NAME 8
typedef struct {
_EBUF_HEADER
u8 id_format;
u8 reserved0;
u8 system_type[CPI_LENGTH_SYSTEM_TYPE];
u64 reserved1;
u8 system_name[CPI_LENGTH_SYSTEM_NAME];
u64 reserved2;
u64 system_level;
u64 reserved3;
u8 sysplex_name[CPI_LENGTH_SYSPLEX_NAME];
u8 reserved4[16];
} __attribute__ ((packed))
cpi_evbuf_t;
typedef struct _cpi_hwcb_t {
_HWCB_HEADER
cpi_evbuf_t cpi_evbuf;
} __attribute__ ((packed))
cpi_hwcb_t;
cpi_hwcb_t *cpi_hwcb;
static int __init cpi_module_init (void);
static void __exit cpi_module_exit (void);
module_init (cpi_module_init);
module_exit (cpi_module_exit);
MODULE_AUTHOR (
"Martin Peschke, IBM Deutschland Entwicklung GmbH "
"<mpeschke@de.ibm.com>");
MODULE_DESCRIPTION (
"identify this operating system instance to the S/390 or zSeries hardware");
static char *system_name = NULL;
MODULE_PARM (system_name, "s");
MODULE_PARM_DESC (system_name, "e.g. hostname - max. 8 characters");
static char *sysplex_name = NULL;
#ifdef ALLOW_SYSPLEX_NAME
MODULE_PARM (sysplex_name, "s");
MODULE_PARM_DESC (sysplex_name, "if applicable - max. 8 characters");
#endif
static char *system_type = "LINUX";
hwc_request_t cpi_request =
{};
hwc_callback_t cpi_callback;
static DECLARE_MUTEX_LOCKED (sem);
static int __init
cpi_module_init (void)
{
int retval;
int system_type_length;
int system_name_length;
int sysplex_name_length = 0;
int retries;
if (!MACHINE_HAS_HWC) {
printk ("cpi: bug: hardware console not present\n");
retval = -EINVAL;
goto out;
}
if (!system_type) {
printk ("cpi: bug: no system type specified\n");
retval = -EINVAL;
goto out;
}
system_type_length = strlen (system_type);
if (system_type_length > CPI_LENGTH_SYSTEM_NAME) {
printk ("cpi: bug: system type has length of %i characters - "
"only %i characters supported\n",
system_type_length,
CPI_LENGTH_SYSTEM_TYPE);
retval = -EINVAL;
goto out;
}
if (!system_name) {
printk ("cpi: no system name specified\n");
retval = -EINVAL;
goto out;
}
system_name_length = strlen (system_name);
if (system_name_length > CPI_LENGTH_SYSTEM_NAME) {
printk ("cpi: system name has length of %i characters - "
"only %i characters supported\n",
system_name_length,
CPI_LENGTH_SYSTEM_NAME);
retval = -EINVAL;
goto out;
}
if (sysplex_name) {
sysplex_name_length = strlen (sysplex_name);
if (sysplex_name_length > CPI_LENGTH_SYSPLEX_NAME) {
printk ("cpi: sysplex name has length of %i characters - "
"only %i characters supported\n",
sysplex_name_length,
CPI_LENGTH_SYSPLEX_NAME);
retval = -EINVAL;
goto out;
}
}
cpi_hwcb = kmalloc (sizeof (cpi_hwcb_t), GFP_KERNEL);
if (!cpi_hwcb) {
printk ("cpi: no storage to fulfill request\n");
retval = -ENOMEM;
goto out;
}
memset (cpi_hwcb, 0, sizeof (cpi_hwcb_t));
cpi_hwcb->length = sizeof (cpi_hwcb_t);
cpi_hwcb->cpi_evbuf.length = sizeof (cpi_evbuf_t);
cpi_hwcb->cpi_evbuf.type = 0x0B;
memset (cpi_hwcb->cpi_evbuf.system_type, ' ', CPI_LENGTH_SYSTEM_TYPE);
memcpy (cpi_hwcb->cpi_evbuf.system_type, system_type, system_type_length);
HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.system_type, CPI_LENGTH_SYSTEM_TYPE);
EBC_TOUPPER (cpi_hwcb->cpi_evbuf.system_type, CPI_LENGTH_SYSTEM_TYPE);
memset (cpi_hwcb->cpi_evbuf.system_name, ' ', CPI_LENGTH_SYSTEM_NAME);
memcpy (cpi_hwcb->cpi_evbuf.system_name, system_name, system_name_length);
HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.system_name, CPI_LENGTH_SYSTEM_NAME);
EBC_TOUPPER (cpi_hwcb->cpi_evbuf.system_name, CPI_LENGTH_SYSTEM_NAME);
cpi_hwcb->cpi_evbuf.system_level = LINUX_VERSION_CODE;
if (sysplex_name) {
memset (cpi_hwcb->cpi_evbuf.sysplex_name, ' ', CPI_LENGTH_SYSPLEX_NAME);
memcpy (cpi_hwcb->cpi_evbuf.sysplex_name, sysplex_name, sysplex_name_length);
HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.sysplex_name, CPI_LENGTH_SYSPLEX_NAME);
EBC_TOUPPER (cpi_hwcb->cpi_evbuf.sysplex_name, CPI_LENGTH_SYSPLEX_NAME);
}
cpi_request.block = cpi_hwcb;
cpi_request.word = HWC_CMDW_WRITEDATA;
cpi_request.callback = cpi_callback;
for (retries = CPI_RETRIES; retries; retries--) {
retval = hwc_send (&cpi_request);
if (retval) {
set_current_state (TASK_INTERRUPTIBLE);
schedule_timeout (CPI_SLEEP_TICKS);
} else {
down (&sem);
switch (cpi_hwcb->response_code) {
case 0x0020:
printk ("cpi: succeeded\n");
break;
default:
printk ("cpi: failed with response code 0x%x\n",
cpi_hwcb->response_code);
}
goto free;
}
}
printk ("cpi: failed (%i)\n", retval);
free:
kfree (cpi_hwcb);
out:
return retval;
}
static void __exit
cpi_module_exit (void)
{
printk ("cpi: exit\n");
}
void
cpi_callback (hwc_request_t * req)
{
up (&sem);
}
This diff is collapsed.
/*
* drivers/s390/char/hwc_rw.h
* interface to the HWC-read/write driver
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
*/
#ifndef __HWC_RW_H__
#define __HWC_RW_H__
#include <linux/ioctl.h>
typedef struct {
void (*move_input) (unsigned char *, unsigned int);
void (*wake_up) (void);
} hwc_high_level_calls_t;
struct _hwc_request;
typedef void hwc_callback_t (struct _hwc_request *);
typedef struct _hwc_request {
void *block;
u32 word;
hwc_callback_t *callback;
void *data;
} __attribute__ ((packed))
hwc_request_t;
#define HWC_ASCEBC(x) ((MACHINE_IS_VM ? _ascebc[x] : _ascebc_500[x]))
#define HWC_EBCASC_STR(s,c) ((MACHINE_IS_VM ? EBCASC(s,c) : EBCASC_500(s,c)))
#define HWC_ASCEBC_STR(s,c) ((MACHINE_IS_VM ? ASCEBC(s,c) : ASCEBC_500(s,c)))
#define IN_HWCB 1
#define IN_WRITE_BUF 2
#define IN_BUFS_TOTAL (IN_HWCB | IN_WRITE_BUF)
typedef unsigned short int ioctl_htab_t;
typedef unsigned char ioctl_echo_t;
typedef unsigned short int ioctl_cols_t;
typedef signed char ioctl_nl_t;
typedef unsigned short int ioctl_obuf_t;
typedef unsigned char ioctl_case_t;
typedef unsigned char ioctl_delim_t;
typedef struct {
ioctl_htab_t width_htab;
ioctl_echo_t echo;
ioctl_cols_t columns;
ioctl_nl_t final_nl;
ioctl_obuf_t max_hwcb;
ioctl_obuf_t kmem_hwcb;
ioctl_case_t tolower;
ioctl_delim_t delim;
} hwc_ioctls_t;
extern hwc_ioctls_t _hwc_ioctls;
#define HWC_IOCTL_LETTER 'B'
#define TIOCHWCSHTAB _IOW(HWC_IOCTL_LETTER, 0, _hwc_ioctls.width_htab)
#define TIOCHWCSECHO _IOW(HWC_IOCTL_LETTER, 1, _hwc_ioctls.echo)
#define TIOCHWCSCOLS _IOW(HWC_IOCTL_LETTER, 2, _hwc_ioctls.columns)
#define TIOCHWCSNL _IOW(HWC_IOCTL_LETTER, 4, _hwc_ioctls.final_nl)
#define TIOCHWCSOBUF _IOW(HWC_IOCTL_LETTER, 5, _hwc_ioctls.max_hwcb)
#define TIOCHWCSINIT _IO(HWC_IOCTL_LETTER, 6)
#define TIOCHWCSCASE _IOW(HWC_IOCTL_LETTER, 7, _hwc_ioctls.tolower)
#define TIOCHWCSDELIM _IOW(HWC_IOCTL_LETTER, 9, _hwc_ioctls.delim)
#define TIOCHWCGHTAB _IOR(HWC_IOCTL_LETTER, 10, _hwc_ioctls.width_htab)
#define TIOCHWCGECHO _IOR(HWC_IOCTL_LETTER, 11, _hwc_ioctls.echo)
#define TIOCHWCGCOLS _IOR(HWC_IOCTL_LETTER, 12, _hwc_ioctls.columns)
#define TIOCHWCGNL _IOR(HWC_IOCTL_LETTER, 14, _hwc_ioctls.final_nl)
#define TIOCHWCGOBUF _IOR(HWC_IOCTL_LETTER, 15, _hwc_ioctls.max_hwcb)
#define TIOCHWCGINIT _IOR(HWC_IOCTL_LETTER, 16, _hwc_ioctls)
#define TIOCHWCGCASE _IOR(HWC_IOCTL_LETTER, 17, _hwc_ioctls.tolower)
#define TIOCHWCGDELIM _IOR(HWC_IOCTL_LETTER, 19, _hwc_ioctls.delim)
#define TIOCHWCGKBUF _IOR(HWC_IOCTL_LETTER, 20, _hwc_ioctls.max_hwcb)
#define TIOCHWCGCURR _IOR(HWC_IOCTL_LETTER, 21, _hwc_ioctls)
#ifndef __HWC_RW_C__
extern int hwc_init (void);
extern int hwc_write (int from_user, const unsigned char *, unsigned int);
extern unsigned int hwc_chars_in_buffer (unsigned char);
extern unsigned int hwc_write_room (unsigned char);
extern void hwc_flush_buffer (unsigned char);
extern void hwc_unblank (void);
extern signed int hwc_ioctl (unsigned int, unsigned long);
extern void do_hwc_interrupt (void);
extern int hwc_printk (const char *,...);
extern signed int hwc_register_calls (hwc_high_level_calls_t *);
extern signed int hwc_unregister_calls (hwc_high_level_calls_t *);
extern int hwc_send (hwc_request_t *);
#endif
#endif
/*
* drivers/s390/char/hwc_tty.c
* HWC line mode terminal driver.
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
*
* Thanks to Martin Schwidefsky.
*/
#include <linux/config.h>
#include <linux/major.h>
#include <linux/termios.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include "hwc_rw.h"
#include "ctrlchar.h"
#define HWC_TTY_PRINT_HEADER "hwc tty driver: "
#define HWC_TTY_BUF_SIZE 512
typedef struct {
struct tty_struct *tty;
unsigned char buf[HWC_TTY_BUF_SIZE];
unsigned short int buf_count;
spinlock_t lock;
hwc_high_level_calls_t calls;
} hwc_tty_data_struct;
static hwc_tty_data_struct hwc_tty_data =
{ /* NULL/0 */ };
static struct tty_driver hwc_tty_driver;
static struct tty_struct *hwc_tty_table[1];
static struct termios *hwc_tty_termios[1];
static struct termios *hwc_tty_termios_locked[1];
static int hwc_tty_refcount = 0;
extern struct termios tty_std_termios;
void hwc_tty_wake_up (void);
void hwc_tty_input (unsigned char *, unsigned int);
static int
hwc_tty_open (struct tty_struct *tty,
struct file *filp)
{
if (minor (tty->device) - tty->driver.minor_start)
return -ENODEV;
tty->driver_data = &hwc_tty_data;
hwc_tty_data.buf_count = 0;
hwc_tty_data.tty = tty;
tty->low_latency = 0;
hwc_tty_data.calls.wake_up = hwc_tty_wake_up;
hwc_tty_data.calls.move_input = hwc_tty_input;
hwc_register_calls (&(hwc_tty_data.calls));
return 0;
}
static void
hwc_tty_close (struct tty_struct *tty,
struct file *filp)
{
if (minor (tty->device) != tty->driver.minor_start) {
printk (KERN_WARNING HWC_TTY_PRINT_HEADER
"do not close hwc tty because of wrong device number");
return;
}
if (tty->count > 1)
return;
hwc_tty_data.tty = NULL;
hwc_unregister_calls (&(hwc_tty_data.calls));
}
static int
hwc_tty_write_room (struct tty_struct *tty)
{
int retval;
retval = hwc_write_room (IN_BUFS_TOTAL);
return retval;
}
static int
hwc_tty_write (struct tty_struct *tty,
int from_user,
const unsigned char *buf,
int count)
{
int retval;
if (hwc_tty_data.buf_count > 0) {
hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
hwc_tty_data.buf_count = 0;
}
retval = hwc_write (from_user, buf, count);
return retval;
}
static void
hwc_tty_put_char (struct tty_struct *tty,
unsigned char ch)
{
unsigned long flags;
spin_lock_irqsave (&hwc_tty_data.lock, flags);
if (hwc_tty_data.buf_count >= HWC_TTY_BUF_SIZE) {
hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
hwc_tty_data.buf_count = 0;
}
hwc_tty_data.buf[hwc_tty_data.buf_count] = ch;
hwc_tty_data.buf_count++;
spin_unlock_irqrestore (&hwc_tty_data.lock, flags);
}
static void
hwc_tty_flush_chars (struct tty_struct *tty)
{
unsigned long flags;
spin_lock_irqsave (&hwc_tty_data.lock, flags);
hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
hwc_tty_data.buf_count = 0;
spin_unlock_irqrestore (&hwc_tty_data.lock, flags);
}
static int
hwc_tty_chars_in_buffer (struct tty_struct *tty)
{
int retval;
retval = hwc_chars_in_buffer (IN_BUFS_TOTAL);
return retval;
}
static void
hwc_tty_flush_buffer (struct tty_struct *tty)
{
hwc_tty_wake_up ();
}
static int
hwc_tty_ioctl (
struct tty_struct *tty,
struct file *file,
unsigned int cmd,
unsigned long arg)
{
if (tty->flags & (1 << TTY_IO_ERROR))
return -EIO;
return hwc_ioctl (cmd, arg);
}
void
hwc_tty_wake_up (void)
{
if (hwc_tty_data.tty == NULL)
return;
if ((hwc_tty_data.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
hwc_tty_data.tty->ldisc.write_wakeup)
(hwc_tty_data.tty->ldisc.write_wakeup) (hwc_tty_data.tty);
wake_up_interruptible (&hwc_tty_data.tty->write_wait);
}
void
hwc_tty_input (unsigned char *buf, unsigned int count)
{
struct tty_struct *tty = hwc_tty_data.tty;
if (tty != NULL) {
unsigned int cchar = ctrlchar_handle(buf, count, tty);
switch (cchar & CTRLCHAR_MASK) {
case CTRLCHAR_SYSRQ:
return;
case CTRLCHAR_CTRL:
tty->flip.count++;
*tty->flip.flag_buf_ptr++ = TTY_NORMAL;
*tty->flip.char_buf_ptr++ = cchar;
break;
case CTRLCHAR_NONE:
memcpy (tty->flip.char_buf_ptr, buf, count);
if (count < 2 || (
strncmp (buf + count - 2, "^n", 2) ||
strncmp (buf + count - 2, "\0252n", 2))) {
tty->flip.char_buf_ptr[count] = '\n';
count++;
} else
count -= 2;
memset (tty->flip.flag_buf_ptr, TTY_NORMAL, count);
tty->flip.char_buf_ptr += count;
tty->flip.flag_buf_ptr += count;
tty->flip.count += count;
break;
}
tty_flip_buffer_push (tty);
hwc_tty_wake_up ();
}
}
void
hwc_tty_init (void)
{
if (!CONSOLE_IS_HWC)
return;
memset (&hwc_tty_driver, 0, sizeof (struct tty_driver));
memset (&hwc_tty_data, 0, sizeof (hwc_tty_data_struct));
hwc_tty_driver.magic = TTY_DRIVER_MAGIC;
hwc_tty_driver.driver_name = "tty_hwc";
hwc_tty_driver.name = "ttyS";
hwc_tty_driver.name_base = 0;
hwc_tty_driver.major = TTY_MAJOR;
hwc_tty_driver.minor_start = 64;
hwc_tty_driver.num = 1;
hwc_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM;
hwc_tty_driver.subtype = SYSTEM_TYPE_TTY;
hwc_tty_driver.init_termios = tty_std_termios;
hwc_tty_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
hwc_tty_driver.init_termios.c_oflag = ONLCR;
hwc_tty_driver.init_termios.c_lflag = ISIG | ECHO;
hwc_tty_driver.flags = TTY_DRIVER_REAL_RAW;
hwc_tty_driver.refcount = &hwc_tty_refcount;
hwc_tty_driver.table = hwc_tty_table;
hwc_tty_driver.termios = hwc_tty_termios;
hwc_tty_driver.termios_locked = hwc_tty_termios_locked;
hwc_tty_driver.open = hwc_tty_open;
hwc_tty_driver.close = hwc_tty_close;
hwc_tty_driver.write = hwc_tty_write;
hwc_tty_driver.put_char = hwc_tty_put_char;
hwc_tty_driver.flush_chars = hwc_tty_flush_chars;
hwc_tty_driver.write_room = hwc_tty_write_room;
hwc_tty_driver.chars_in_buffer = hwc_tty_chars_in_buffer;
hwc_tty_driver.flush_buffer = hwc_tty_flush_buffer;
hwc_tty_driver.ioctl = hwc_tty_ioctl;
hwc_tty_driver.throttle = NULL;
hwc_tty_driver.unthrottle = NULL;
hwc_tty_driver.send_xchar = NULL;
hwc_tty_driver.set_termios = NULL;
hwc_tty_driver.set_ldisc = NULL;
hwc_tty_driver.stop = NULL;
hwc_tty_driver.start = NULL;
hwc_tty_driver.hangup = NULL;
hwc_tty_driver.break_ctl = NULL;
hwc_tty_driver.wait_until_sent = NULL;
hwc_tty_driver.read_proc = NULL;
hwc_tty_driver.write_proc = NULL;
if (tty_register_driver (&hwc_tty_driver))
panic ("Couldn't register hwc_tty driver\n");
}
This diff is collapsed.
/*
* drivers/s390/char/sclp.h
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#ifndef __SCLP_H__
#define __SCLP_H__
#include <linux/types.h>
#include <linux/list.h>
#include <asm/ebcdic.h>
/* maximum number of pages concerning our own memory management */
#define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
#define MAX_CONSOLE_PAGES 4
#define EvTyp_OpCmd 0x01
#define EvTyp_Msg 0x02
#define EvTyp_StateChange 0x08
#define EvTyp_PMsgCmd 0x09
#define EvTyp_CntlProgOpCmd 0x20
#define EvTyp_CntlProgIdent 0x0B
#define EvTyp_SigQuiesce 0x1D
#define EvTyp_OpCmd_Mask 0x80000000
#define EvTyp_Msg_Mask 0x40000000
#define EvTyp_StateChange_Mask 0x01000000
#define EvTyp_PMsgCmd_Mask 0x00800000
#define EvTyp_CtlProgOpCmd_Mask 0x00000001
#define EvTyp_CtlProgIdent_Mask 0x00200000
#define EvTyp_SigQuiesce_Mask 0x00000008
#define GnrlMsgFlgs_DOM 0x8000
#define GnrlMsgFlgs_SndAlrm 0x4000
#define GnrlMsgFlgs_HoldMsg 0x2000
#define LnTpFlgs_CntlText 0x8000
#define LnTpFlgs_LabelText 0x4000
#define LnTpFlgs_DataText 0x2000
#define LnTpFlgs_EndText 0x1000
#define LnTpFlgs_PromptText 0x0800
#define SCLP_COMMAND_INITIATED 0
#define SCLP_BUSY 2
#define SCLP_NOT_OPERATIONAL 3
typedef unsigned int sclp_cmdw_t;
#define SCLP_CMDW_READDATA 0x00770005
#define SCLP_CMDW_WRITEDATA 0x00760005
#define SCLP_CMDW_WRITEMASK 0x00780005
#define GDS_ID_MDSMU 0x1310
#define GDS_ID_MDSRouteInfo 0x1311
#define GDS_ID_AgUnWrkCorr 0x1549
#define GDS_ID_SNACondReport 0x1532
#define GDS_ID_CPMSU 0x1212
#define GDS_ID_RoutTargInstr 0x154D
#define GDS_ID_OpReq 0x8070
#define GDS_ID_TextCmd 0x1320
#define GDS_KEY_SelfDefTextMsg 0x31
typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */
struct sccb_header {
u16 length;
u8 function_code;
u8 control_mask[3];
u16 response_code;
} __attribute__((packed));
struct gds_subvector {
u8 length;
u8 key;
} __attribute__((packed));
struct gds_vector {
u16 length;
u16 gds_id;
} __attribute__((packed));
struct evbuf_header {
u16 length;
u8 type;
u8 flags;
u16 _reserved;
} __attribute__((packed));
struct sclp_req {
struct list_head list; /* list_head for request queueing. */
sclp_cmdw_t command; /* sclp command to execute */
void *sccb; /* pointer to the sccb to execute */
char status; /* status of this request */
/* Callback that is called after reaching final status. */
void (*callback)(struct sclp_req *, void *data);
void *callback_data;
};
#define SCLP_REQ_FILLED 0x00 /* request is ready to be processed */
#define SCLP_REQ_QUEUED 0x01 /* request is queued to be processed */
#define SCLP_REQ_RUNNING 0x02 /* request is currently running */
#define SCLP_REQ_DONE 0x03 /* request is completed successfully */
#define SCLP_REQ_FAILED 0x05 /* request is finally failed */
/* function pointers that a high level driver has to use for registration */
/* of some routines it wants to be called from the low level driver */
struct sclp_register {
struct list_head list;
/* event masks this user is registered for */
sccb_mask_t receive_mask;
sccb_mask_t send_mask;
/* actually present events */
sccb_mask_t sclp_receive_mask;
sccb_mask_t sclp_send_mask;
/* called if event type availability changes */
void (*state_change_fn)(struct sclp_register *);
/* called for events in cp_receive_mask/sclp_receive_mask */
void (*receiver_fn)(struct evbuf_header *);
};
/* externals from sclp.c */
void sclp_add_request(struct sclp_req *req);
void sclp_sync_wait(void);
int sclp_register(struct sclp_register *reg);
void sclp_unregister(struct sclp_register *reg);
/* useful inlines */
/* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */
/* translate single character from ASCII to EBCDIC */
static inline unsigned char
sclp_ascebc(unsigned char ch)
{
return (MACHINE_IS_VM) ? _ascebc[ch] : _ascebc_500[ch];
}
/* translate string from EBCDIC to ASCII */
static inline void
sclp_ebcasc_str(unsigned char *str, int nr)
{
(MACHINE_IS_VM) ? EBCASC(str, nr) : EBCASC_500(str, nr);
}
/* translate string from ASCII to EBCDIC */
static inline void
sclp_ascebc_str(unsigned char *str, int nr)
{
(MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr);
}
#endif /* __SCLP_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* drivers/s390/char/sclp_rw.h
* interface to the SCLP-read/write driver
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#ifndef __SCLP_RW_H__
#define __SCLP_RW_H__
struct mto {
u16 length;
u16 type;
u16 line_type_flags;
u8 alarm_control;
u8 _reserved[3];
} __attribute__((packed));
struct go {
u16 length;
u16 type;
u32 domid;
u8 hhmmss_time[8];
u8 th_time[3];
u8 reserved_0;
u8 dddyyyy_date[7];
u8 _reserved_1;
u16 general_msg_flags;
u8 _reserved_2[10];
u8 originating_system_name[8];
u8 job_guest_name[8];
} __attribute__((packed));
struct mdb_header {
u16 length;
u16 type;
u32 tag;
u32 revision_code;
} __attribute__((packed));
struct mdb {
struct mdb_header header;
struct go go;
} __attribute__((packed));
struct msg_buf {
struct evbuf_header header;
struct mdb mdb;
} __attribute__((packed));
struct write_sccb {
struct sccb_header header;
struct msg_buf msg_buf;
} __attribute__((packed));
/* The number of empty mto buffers that can be contained in a single sccb. */
#define NR_EMPTY_MTO_PER_SCCB ((PAGE_SIZE - sizeof(struct sclp_buffer) - \
sizeof(struct write_sccb)) / sizeof(struct mto))
/*
* data structure for information about list of SCCBs (only for writing),
* will be located at the end of a SCCBs page
*/
struct sclp_buffer {
struct list_head list; /* list_head for sccb_info chain */
struct sclp_req request;
struct write_sccb *sccb;
char *current_line;
int current_length;
/* output format settings */
unsigned short columns;
unsigned short htab;
/* statistics about this buffer */
unsigned int mto_char_sum; /* # chars in sccb */
unsigned int mto_number; /* # mtos in sccb */
/* Callback that is called after reaching final status. */
void (*callback)(struct sclp_buffer *, int);
};
int sclp_rw_init(void);
struct sclp_buffer *sclp_make_buffer(void *, unsigned short, unsigned short);
void *sclp_unmake_buffer(struct sclp_buffer *);
int sclp_buffer_space(struct sclp_buffer *);
int sclp_write(struct sclp_buffer *buffer, const char *, int, int);
void sclp_move_current_line(struct sclp_buffer *, struct sclp_buffer *);
void sclp_emit_buffer(struct sclp_buffer *,void (*)(struct sclp_buffer *,int));
void sclp_set_columns(struct sclp_buffer *, unsigned short);
void sclp_set_htab(struct sclp_buffer *, unsigned short);
int sclp_chars_in_buffer(struct sclp_buffer *);
#endif /* __SCLP_RW_H__ */
This diff is collapsed.
/*
* drivers/s390/char/sclp_tty.h
* interface to the SCLP-read/write driver
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#ifndef __SCLP_TTY_H__
#define __SCLP_TTY_H__
#include <linux/ioctl.h>
/* This is the type of data structures storing sclp ioctl setting. */
struct sclp_ioctls {
unsigned short htab;
unsigned char echo;
unsigned short columns;
signed char final_nl;
unsigned short max_sccb;
unsigned short kmem_sccb; /* cant be modified at run time */
unsigned char tolower;
unsigned char delim;
};
/* must be unique, FIXME: must be added in Documentation/ioctl_number.txt */
#define SCLP_IOCTL_LETTER 'B'
/* set width of horizontal tabulator */
#define TIOCSCLPSHTAB _IOW(SCLP_IOCTL_LETTER, 0, unsigned short)
/* enable/disable echo of input (independent from line discipline) */
#define TIOCSCLPSECHO _IOW(SCLP_IOCTL_LETTER, 1, unsigned char)
/* set number of colums for output */
#define TIOCSCLPSCOLS _IOW(SCLP_IOCTL_LETTER, 2, unsigned short)
/* enable/disable writing without final new line character */
#define TIOCSCLPSNL _IOW(SCLP_IOCTL_LETTER, 4, signed char)
/* set the maximum buffers size for output, rounded up to next 4kB boundary */
#define TIOCSCLPSOBUF _IOW(SCLP_IOCTL_LETTER, 5, unsigned short)
/* set initial (default) sclp ioctls */
#define TIOCSCLPSINIT _IO(SCLP_IOCTL_LETTER, 6)
/* enable/disable conversion from upper to lower case of input */
#define TIOCSCLPSCASE _IOW(SCLP_IOCTL_LETTER, 7, unsigned char)
/* set special character used for seperating upper and lower case, */
/* 0x00 disables this feature */
#define TIOCSCLPSDELIM _IOW(SCLP_IOCTL_LETTER, 9, unsigned char)
/* get width of horizontal tabulator */
#define TIOCSCLPGHTAB _IOR(SCLP_IOCTL_LETTER, 10, unsigned short)
/* Is echo of input enabled ? (independent from line discipline) */
#define TIOCSCLPGECHO _IOR(SCLP_IOCTL_LETTER, 11, unsigned char)
/* get number of colums for output */
#define TIOCSCLPGCOLS _IOR(SCLP_IOCTL_LETTER, 12, unsigned short)
/* Is writing without final new line character enabled ? */
#define TIOCSCLPGNL _IOR(SCLP_IOCTL_LETTER, 14, signed char)
/* get the maximum buffers size for output */
#define TIOCSCLPGOBUF _IOR(SCLP_IOCTL_LETTER, 15, unsigned short)
/* Is conversion from upper to lower case of input enabled ? */
#define TIOCSCLPGCASE _IOR(SCLP_IOCTL_LETTER, 17, unsigned char)
/* get special character used for seperating upper and lower case, */
/* 0x00 disables this feature */
#define TIOCSCLPGDELIM _IOR(SCLP_IOCTL_LETTER, 19, unsigned char)
/* get the number of buffers/pages got from kernel at startup */
#define TIOCSCLPGKBUF _IOR(SCLP_IOCTL_LETTER, 20, unsigned short)
#endif /* __SCLP_TTY_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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