aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/compat_ioctl.c9
-rw-r--r--arch/s390/kernel/head.S72
-rw-r--r--arch/s390/kernel/head64.S66
-rw-r--r--arch/s390/kernel/setup.c186
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/vtime.c18
6 files changed, 328 insertions, 27 deletions
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
index 24a1e9f069a7..6504c4e69986 100644
--- a/arch/s390/kernel/compat_ioctl.c
+++ b/arch/s390/kernel/compat_ioctl.c
@@ -18,6 +18,8 @@
18#include <asm/dasd.h> 18#include <asm/dasd.h>
19#include <asm/cmb.h> 19#include <asm/cmb.h>
20#include <asm/tape390.h> 20#include <asm/tape390.h>
21#include <asm/ccwdev.h>
22#include "../../../drivers/s390/char/raw3270.h"
21 23
22static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, 24static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
23 unsigned long arg, struct file *f) 25 unsigned long arg, struct file *f)
@@ -62,6 +64,13 @@ COMPATIBLE_IOCTL(BIODASDCMFENABLE)
62COMPATIBLE_IOCTL(BIODASDCMFDISABLE) 64COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
63COMPATIBLE_IOCTL(BIODASDREADALLCMB) 65COMPATIBLE_IOCTL(BIODASDREADALLCMB)
64 66
67COMPATIBLE_IOCTL(TUBICMD)
68COMPATIBLE_IOCTL(TUBOCMD)
69COMPATIBLE_IOCTL(TUBGETI)
70COMPATIBLE_IOCTL(TUBGETO)
71COMPATIBLE_IOCTL(TUBSETMOD)
72COMPATIBLE_IOCTL(TUBGETMOD)
73
65COMPATIBLE_IOCTL(TAPE390_DISPLAY) 74COMPATIBLE_IOCTL(TAPE390_DISPLAY)
66 75
67/* s390 doesn't need handlers here */ 76/* s390 doesn't need handlers here */
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 55654b6e16dc..039354d72348 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -485,7 +485,9 @@ start:
485# 485#
486 .org 0x10000 486 .org 0x10000
487startup:basr %r13,0 # get base 487startup:basr %r13,0 # get base
488.LPG1: lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 488.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13)
489 basr %r14, %r1
490 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
489 la %r12,_pstart-.LPG1(%r13) # pointer to parameter area 491 la %r12,_pstart-.LPG1(%r13) # pointer to parameter area
490 # move IPL device to lowcore 492 # move IPL device to lowcore
491 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) 493 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
@@ -560,6 +562,9 @@ startup:basr %r13,0 # get base
560 mr %r2,%r1 # mem size in bytes in %r3 562 mr %r2,%r1 # mem size in bytes in %r3
561 b .Lfchunk-.LPG1(%r13) 563 b .Lfchunk-.LPG1(%r13)
562 564
565 .align 4
566.Lget_ipl_device_addr:
567 .long .Lget_ipl_device
563.Lpmask: 568.Lpmask:
564 .byte 0 569 .byte 0
565.align 8 570.align 8
@@ -755,6 +760,63 @@ _pstart:
755 .global _pend 760 .global _pend
756_pend: 761_pend:
757 762
763.Lget_ipl_device:
764 basr %r12,0
765.LPG2: l %r1,0xb8 # get sid
766 sll %r1,15 # test if subchannel is enabled
767 srl %r1,31
768 ltr %r1,%r1
769 bz 0(%r14) # subchannel disabled
770 l %r1,0xb8
771 la %r5,.Lipl_schib-.LPG2(%r12)
772 stsch 0(%r5) # get schib of subchannel
773 bnz 0(%r14) # schib not available
774 tm 5(%r5),0x01 # devno valid?
775 bno 0(%r14)
776 la %r6,ipl_parameter_flags-.LPG2(%r12)
777 oi 3(%r6),0x01 # set flag
778 la %r2,ipl_devno-.LPG2(%r12)
779 mvc 0(2,%r2),6(%r5) # store devno
780 tm 4(%r5),0x80 # qdio capable device?
781 bno 0(%r14)
782 oi 3(%r6),0x02 # set flag
783
784 # copy ipl parameters
785
786 lhi %r0,4096
787 l %r2,20(%r0) # get address of parameter list
788 lhi %r3,IPL_PARMBLOCK_ORIGIN
789 st %r3,20(%r0)
790 lhi %r4,1
791 cr %r2,%r3 # start parameters < destination ?
792 jl 0f
793 lhi %r1,1 # copy direction is upwards
794 j 1f
7950: lhi %r1,-1 # copy direction is downwards
796 ar %r2,%r0
797 ar %r3,%r0
798 ar %r2,%r1
799 ar %r3,%r1
8001: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
801 ar %r3,%r1
802 ar %r2,%r1
803 sr %r0,%r4
804 jne 1b
805 b 0(%r14)
806
807 .align 4
808.Lipl_schib:
809 .rept 13
810 .long 0
811 .endr
812
813 .globl ipl_parameter_flags
814ipl_parameter_flags:
815 .long 0
816 .globl ipl_devno
817ipl_devno:
818 .word 0
819
758#ifdef CONFIG_SHARED_KERNEL 820#ifdef CONFIG_SHARED_KERNEL
759 .org 0x100000 821 .org 0x100000
760#endif 822#endif
@@ -764,11 +826,11 @@ _pend:
764# 826#
765 .globl _stext 827 .globl _stext
766_stext: basr %r13,0 # get base 828_stext: basr %r13,0 # get base
767.LPG2: 829.LPG3:
768# 830#
769# Setup stack 831# Setup stack
770# 832#
771 l %r15,.Linittu-.LPG2(%r13) 833 l %r15,.Linittu-.LPG3(%r13)
772 mvc __LC_CURRENT(4),__TI_task(%r15) 834 mvc __LC_CURRENT(4),__TI_task(%r15)
773 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE 835 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
774 st %r15,__LC_KERNEL_STACK # set end of kernel stack 836 st %r15,__LC_KERNEL_STACK # set end of kernel stack
@@ -782,8 +844,8 @@ _stext: basr %r13,0 # get base
782 lctl %c0,%c15,0(%r15) 844 lctl %c0,%c15,0(%r15)
783 845
784# 846#
785 lam 0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess 847 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
786 l %r14,.Lstart-.LPG2(%r13) 848 l %r14,.Lstart-.LPG3(%r13)
787 basr %r14,%r14 # call start_kernel 849 basr %r14,%r14 # call start_kernel
788# 850#
789# We returned from start_kernel ?!? PANIK 851# We returned from start_kernel ?!? PANIK
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index c9ff0404c875..193aafa72f54 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -484,6 +484,8 @@ start:
484startup:basr %r13,0 # get base 484startup:basr %r13,0 # get base
485.LPG1: sll %r13,1 # remove high order bit 485.LPG1: sll %r13,1 # remove high order bit
486 srl %r13,1 486 srl %r13,1
487 l %r1,.Lget_ipl_device_addr-.LPG1(%r13)
488 basr %r14,%r1
487 lhi %r1,1 # mode 1 = esame 489 lhi %r1,1 # mode 1 = esame
488 slr %r0,%r0 # set cpuid to zero 490 slr %r0,%r0 # set cpuid to zero
489 sigp %r1,%r0,0x12 # switch to esame mode 491 sigp %r1,%r0,0x12 # switch to esame mode
@@ -556,6 +558,9 @@ startup:basr %r13,0 # get base
556 mlgr %r2,%r1 # mem size in bytes in %r3 558 mlgr %r2,%r1 # mem size in bytes in %r3
557 b .Lfchunk-.LPG1(%r13) 559 b .Lfchunk-.LPG1(%r13)
558 560
561 .align 4
562.Lget_ipl_device_addr:
563 .long .Lget_ipl_device
559.Lpmask: 564.Lpmask:
560 .byte 0 565 .byte 0
561 .align 8 566 .align 8
@@ -746,6 +751,63 @@ _pstart:
746 .global _pend 751 .global _pend
747_pend: 752_pend:
748 753
754.Lget_ipl_device:
755 basr %r12,0
756.LPG2: l %r1,0xb8 # get sid
757 sll %r1,15 # test if subchannel is enabled
758 srl %r1,31
759 ltr %r1,%r1
760 bz 0(%r14) # subchannel disabled
761 l %r1,0xb8
762 la %r5,.Lipl_schib-.LPG2(%r12)
763 stsch 0(%r5) # get schib of subchannel
764 bnz 0(%r14) # schib not available
765 tm 5(%r5),0x01 # devno valid?
766 bno 0(%r14)
767 la %r6,ipl_parameter_flags-.LPG2(%r12)
768 oi 3(%r6),0x01 # set flag
769 la %r2,ipl_devno-.LPG2(%r12)
770 mvc 0(2,%r2),6(%r5) # store devno
771 tm 4(%r5),0x80 # qdio capable device?
772 bno 0(%r14)
773 oi 3(%r6),0x02 # set flag
774
775 # copy ipl parameters
776
777 lhi %r0,4096
778 l %r2,20(%r0) # get address of parameter list
779 lhi %r3,IPL_PARMBLOCK_ORIGIN
780 st %r3,20(%r0)
781 lhi %r4,1
782 cr %r2,%r3 # start parameters < destination ?
783 jl 0f
784 lhi %r1,1 # copy direction is upwards
785 j 1f
7860: lhi %r1,-1 # copy direction is downwards
787 ar %r2,%r0
788 ar %r3,%r0
789 ar %r2,%r1
790 ar %r3,%r1
7911: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
792 ar %r3,%r1
793 ar %r2,%r1
794 sr %r0,%r4
795 jne 1b
796 b 0(%r14)
797
798 .align 4
799.Lipl_schib:
800 .rept 13
801 .long 0
802 .endr
803
804 .globl ipl_parameter_flags
805ipl_parameter_flags:
806 .long 0
807 .globl ipl_devno
808ipl_devno:
809 .word 0
810
749#ifdef CONFIG_SHARED_KERNEL 811#ifdef CONFIG_SHARED_KERNEL
750 .org 0x100000 812 .org 0x100000
751#endif 813#endif
@@ -755,7 +817,7 @@ _pend:
755# 817#
756 .globl _stext 818 .globl _stext
757_stext: basr %r13,0 # get base 819_stext: basr %r13,0 # get base
758.LPG2: 820.LPG3:
759# 821#
760# Setup stack 822# Setup stack
761# 823#
@@ -774,7 +836,7 @@ _stext: basr %r13,0 # get base
774 lctlg %c0,%c15,0(%r15) 836 lctlg %c0,%c15,0(%r15)
775 837
776# 838#
777 lam 0,15,.Laregs-.LPG2(%r13) # load access regs needed by uaccess 839 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
778 brasl %r14,start_kernel # go to C code 840 brasl %r14,start_kernel # go to C code
779# 841#
780# We returned from start_kernel ?!? PANIK 842# We returned from start_kernel ?!? PANIK
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 5204778b8e5e..31e7b19348b7 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -36,6 +36,7 @@
36#include <linux/console.h> 36#include <linux/console.h>
37#include <linux/seq_file.h> 37#include <linux/seq_file.h>
38#include <linux/kernel_stat.h> 38#include <linux/kernel_stat.h>
39#include <linux/device.h>
39 40
40#include <asm/uaccess.h> 41#include <asm/uaccess.h>
41#include <asm/system.h> 42#include <asm/system.h>
@@ -685,3 +686,188 @@ struct seq_operations cpuinfo_op = {
685 .show = show_cpuinfo, 686 .show = show_cpuinfo,
686}; 687};
687 688
689#define DEFINE_IPL_ATTR(_name, _format, _value) \
690static ssize_t ipl_##_name##_show(struct subsystem *subsys, \
691 char *page) \
692{ \
693 return sprintf(page, _format, _value); \
694} \
695static struct subsys_attribute ipl_##_name##_attr = \
696 __ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);
697
698DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long)
699 IPL_PARMBLOCK_START->fcp.wwpn);
700DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long)
701 IPL_PARMBLOCK_START->fcp.lun);
702DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long)
703 IPL_PARMBLOCK_START->fcp.bootprog);
704DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long)
705 IPL_PARMBLOCK_START->fcp.br_lba);
706
707enum ipl_type_type {
708 ipl_type_unknown,
709 ipl_type_ccw,
710 ipl_type_fcp,
711};
712
713static enum ipl_type_type
714get_ipl_type(void)
715{
716 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
717
718 if (!IPL_DEVNO_VALID)
719 return ipl_type_unknown;
720 if (!IPL_PARMBLOCK_VALID)
721 return ipl_type_ccw;
722 if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION)
723 return ipl_type_unknown;
724 if (ipl->fcp.pbt != IPL_TYPE_FCP)
725 return ipl_type_unknown;
726 return ipl_type_fcp;
727}
728
729static ssize_t
730ipl_type_show(struct subsystem *subsys, char *page)
731{
732 switch (get_ipl_type()) {
733 case ipl_type_ccw:
734 return sprintf(page, "ccw\n");
735 case ipl_type_fcp:
736 return sprintf(page, "fcp\n");
737 default:
738 return sprintf(page, "unknown\n");
739 }
740}
741
742static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);
743
744static ssize_t
745ipl_device_show(struct subsystem *subsys, char *page)
746{
747 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
748
749 switch (get_ipl_type()) {
750 case ipl_type_ccw:
751 return sprintf(page, "0.0.%04x\n", ipl_devno);
752 case ipl_type_fcp:
753 return sprintf(page, "0.0.%04x\n", ipl->fcp.devno);
754 default:
755 return 0;
756 }
757}
758
759static struct subsys_attribute ipl_device_attr =
760 __ATTR(device, S_IRUGO, ipl_device_show, NULL);
761
762static struct attribute *ipl_fcp_attrs[] = {
763 &ipl_type_attr.attr,
764 &ipl_device_attr.attr,
765 &ipl_wwpn_attr.attr,
766 &ipl_lun_attr.attr,
767 &ipl_bootprog_attr.attr,
768 &ipl_br_lba_attr.attr,
769 NULL,
770};
771
772static struct attribute_group ipl_fcp_attr_group = {
773 .attrs = ipl_fcp_attrs,
774};
775
776static struct attribute *ipl_ccw_attrs[] = {
777 &ipl_type_attr.attr,
778 &ipl_device_attr.attr,
779 NULL,
780};
781
782static struct attribute_group ipl_ccw_attr_group = {
783 .attrs = ipl_ccw_attrs,
784};
785
786static struct attribute *ipl_unknown_attrs[] = {
787 &ipl_type_attr.attr,
788 NULL,
789};
790
791static struct attribute_group ipl_unknown_attr_group = {
792 .attrs = ipl_unknown_attrs,
793};
794
795static ssize_t
796ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
797{
798 unsigned int size = IPL_PARMBLOCK_SIZE;
799
800 if (off > size)
801 return 0;
802 if (off + count > size)
803 count = size - off;
804
805 memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count);
806 return count;
807}
808
809static struct bin_attribute ipl_parameter_attr = {
810 .attr = {
811 .name = "binary_parameter",
812 .mode = S_IRUGO,
813 .owner = THIS_MODULE,
814 },
815 .size = PAGE_SIZE,
816 .read = &ipl_parameter_read,
817};
818
819static ssize_t
820ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
821{
822 unsigned int size = IPL_PARMBLOCK_START->fcp.scp_data_len;
823 void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data;
824
825 if (off > size)
826 return 0;
827 if (off + count > size)
828 count = size - off;
829
830 memcpy(buf, scp_data + off, count);
831 return count;
832}
833
834static struct bin_attribute ipl_scp_data_attr = {
835 .attr = {
836 .name = "scp_data",
837 .mode = S_IRUGO,
838 .owner = THIS_MODULE,
839 },
840 .size = PAGE_SIZE,
841 .read = &ipl_scp_data_read,
842};
843
844static decl_subsys(ipl, NULL, NULL);
845
846static int __init
847ipl_device_sysfs_register(void) {
848 int rc;
849
850 rc = firmware_register(&ipl_subsys);
851 if (rc)
852 return rc;
853
854 switch (get_ipl_type()) {
855 case ipl_type_ccw:
856 sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group);
857 break;
858 case ipl_type_fcp:
859 sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
860 sysfs_create_bin_file(&ipl_subsys.kset.kobj,
861 &ipl_parameter_attr);
862 sysfs_create_bin_file(&ipl_subsys.kset.kobj,
863 &ipl_scp_data_attr);
864 break;
865 default:
866 sysfs_create_group(&ipl_subsys.kset.kobj,
867 &ipl_unknown_attr_group);
868 break;
869 }
870 return 0;
871}
872
873__initcall(ipl_device_sysfs_register);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2fd75da15495..9a1d95894f3d 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -49,10 +49,6 @@
49 49
50#define TICK_SIZE tick 50#define TICK_SIZE tick
51 51
52u64 jiffies_64 = INITIAL_JIFFIES;
53
54EXPORT_SYMBOL(jiffies_64);
55
56static ext_int_info_t ext_int_info_cc; 52static ext_int_info_t ext_int_info_cc;
57static u64 init_timer_cc; 53static u64 init_timer_cc;
58static u64 jiffies_timer_cc; 54static u64 jiffies_timer_cc;
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index fa0726507b3d..22a895ecb7a4 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -24,7 +24,6 @@
24#include <asm/s390_ext.h> 24#include <asm/s390_ext.h>
25#include <asm/timer.h> 25#include <asm/timer.h>
26 26
27#define VTIMER_MAGIC (TIMER_MAGIC + 1)
28static ext_int_info_t ext_int_info_timer; 27static ext_int_info_t ext_int_info_timer;
29DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); 28DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
30 29
@@ -277,20 +276,12 @@ static void do_cpu_timer_interrupt(struct pt_regs *regs, __u16 error_code)
277 276
278void init_virt_timer(struct vtimer_list *timer) 277void init_virt_timer(struct vtimer_list *timer)
279{ 278{
280 timer->magic = VTIMER_MAGIC;
281 timer->function = NULL; 279 timer->function = NULL;
282 INIT_LIST_HEAD(&timer->entry); 280 INIT_LIST_HEAD(&timer->entry);
283 spin_lock_init(&timer->lock); 281 spin_lock_init(&timer->lock);
284} 282}
285EXPORT_SYMBOL(init_virt_timer); 283EXPORT_SYMBOL(init_virt_timer);
286 284
287static inline int check_vtimer(struct vtimer_list *timer)
288{
289 if (timer->magic != VTIMER_MAGIC)
290 return -EINVAL;
291 return 0;
292}
293
294static inline int vtimer_pending(struct vtimer_list *timer) 285static inline int vtimer_pending(struct vtimer_list *timer)
295{ 286{
296 return (!list_empty(&timer->entry)); 287 return (!list_empty(&timer->entry));
@@ -346,7 +337,7 @@ static void internal_add_vtimer(struct vtimer_list *timer)
346 337
347static inline int prepare_vtimer(struct vtimer_list *timer) 338static inline int prepare_vtimer(struct vtimer_list *timer)
348{ 339{
349 if (check_vtimer(timer) || !timer->function) { 340 if (!timer->function) {
350 printk("add_virt_timer: uninitialized timer\n"); 341 printk("add_virt_timer: uninitialized timer\n");
351 return -EINVAL; 342 return -EINVAL;
352 } 343 }
@@ -414,7 +405,7 @@ int mod_virt_timer(struct vtimer_list *timer, __u64 expires)
414 unsigned long flags; 405 unsigned long flags;
415 int cpu; 406 int cpu;
416 407
417 if (check_vtimer(timer) || !timer->function) { 408 if (!timer->function) {
418 printk("mod_virt_timer: uninitialized timer\n"); 409 printk("mod_virt_timer: uninitialized timer\n");
419 return -EINVAL; 410 return -EINVAL;
420 } 411 }
@@ -481,11 +472,6 @@ int del_virt_timer(struct vtimer_list *timer)
481 unsigned long flags; 472 unsigned long flags;
482 struct vtimer_queue *vt_list; 473 struct vtimer_queue *vt_list;
483 474
484 if (check_vtimer(timer)) {
485 printk("del_virt_timer: timer not initialized\n");
486 return -EINVAL;
487 }
488
489 /* check if timer is pending */ 475 /* check if timer is pending */
490 if (!vtimer_pending(timer)) 476 if (!vtimer_pending(timer))
491 return 0; 477 return 0;