diff options
-rw-r--r-- | arch/s390/include/asm/cio.h | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/ipl.h | 1 | ||||
-rw-r--r-- | arch/s390/include/asm/reset.h | 20 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 209 | ||||
-rw-r--r-- | arch/s390/kernel/machine_kexec.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/reipl.S | 87 | ||||
-rw-r--r-- | arch/s390/kernel/relocate_kernel.S | 54 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 224 | ||||
-rw-r--r-- | drivers/s390/cio/ioasm.c | 24 | ||||
-rw-r--r-- | drivers/s390/cio/ioasm.h | 1 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 23 |
11 files changed, 16 insertions, 630 deletions
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 80c1179bc666..225667652069 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -328,8 +328,6 @@ static inline u8 pathmask_to_pos(u8 mask) void channel_subsystem_reinit(void); extern void css_schedule_reprobe(void); -extern void reipl_ccw_dev(struct ccw_dev_id *id); - /* Function from drivers/s390/cio/chsc.c */ int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta); int chsc_sstpi(void *page, void *result, size_t size); diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index eb10df9ef607..b218019ff8f3 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -87,6 +87,7 @@ struct save_area * __init save_area_boot_cpu(void); void __init save_area_add_regs(struct save_area *, void *regs); void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs); +extern void s390_reset_system(void); extern void do_reipl(void); extern void do_halt(void); extern void do_poff(void); diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h deleted file mode 100644 index 6450b31ade03..000000000000 --- a/arch/s390/include/asm/reset.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright IBM Corp. 2006 - * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> - */ - -#ifndef _ASM_S390_RESET_H -#define _ASM_S390_RESET_H - -#include <linux/list.h> - -struct reset_call { - struct list_head list; - void (*fn)(void); -}; - -extern void register_reset_call(struct reset_call *reset); -extern void unregister_reset_call(struct reset_call *reset); -extern void s390_reset_system(void); -#endif /* _ASM_S390_RESET_H */ diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 39572ee8e2a7..db86c67f48ec 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -25,7 +25,6 @@ #include <asm/setup.h> #include <asm/cpcmd.h> #include <asm/ebcdic.h> -#include <asm/reset.h> #include <asm/sclp.h> #include <asm/checksum.h> #include <asm/debug.h> @@ -119,29 +118,20 @@ static char *dump_type_str(enum dump_type type) } enum ipl_method { - REIPL_METHOD_CCW_CIO, REIPL_METHOD_CCW_DIAG, - REIPL_METHOD_CCW_VM, - REIPL_METHOD_FCP_RO_DIAG, - REIPL_METHOD_FCP_RW_DIAG, - REIPL_METHOD_FCP_RO_VM, + REIPL_METHOD_FCP_DIAG, REIPL_METHOD_FCP_DUMP, - REIPL_METHOD_NSS, REIPL_METHOD_NSS_DIAG, REIPL_METHOD_DEFAULT, }; enum dump_method { DUMP_METHOD_NONE, - DUMP_METHOD_CCW_CIO, DUMP_METHOD_CCW_DIAG, - DUMP_METHOD_CCW_VM, DUMP_METHOD_FCP_DIAG, }; static int ipl_block_valid; -static int diag308_set_works; - static struct ipl_parameter_block ipl_block; static int reipl_capabilities = IPL_TYPE_UNKNOWN; @@ -256,14 +246,6 @@ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ sys_##_prefix##_##_name##_show, \ sys_##_prefix##_##_name##_store) -static void make_attrs_ro(struct attribute **attrs) -{ - while (*attrs) { - (*attrs)->mode = S_IRUGO; - attrs++; - } -} - /* * ipl section */ @@ -541,10 +523,6 @@ static void __ipl_run(void *unused) { __bpon(); diag308(DIAG308_LOAD_CLEAR, NULL); - if (MACHINE_IS_VM) - __cpcmd("IPL", NULL, 0, NULL); - else if (ipl_info.type == IPL_TYPE_CCW) - reipl_ccw_dev(&ipl_info.data.ccw.dev_id); } static void ipl_run(struct shutdown_trigger *trigger) @@ -951,31 +929,18 @@ static int reipl_set_type(enum ipl_type type) switch(type) { case IPL_TYPE_CCW: - if (diag308_set_works) - reipl_method = REIPL_METHOD_CCW_DIAG; - else if (MACHINE_IS_VM) - reipl_method = REIPL_METHOD_CCW_VM; - else - reipl_method = REIPL_METHOD_CCW_CIO; + reipl_method = REIPL_METHOD_CCW_DIAG; set_reipl_block_actual(reipl_block_ccw); break; case IPL_TYPE_FCP: - if (diag308_set_works) - reipl_method = REIPL_METHOD_FCP_RW_DIAG; - else if (MACHINE_IS_VM) - reipl_method = REIPL_METHOD_FCP_RO_VM; - else - reipl_method = REIPL_METHOD_FCP_RO_DIAG; + reipl_method = REIPL_METHOD_FCP_DIAG; set_reipl_block_actual(reipl_block_fcp); break; case IPL_TYPE_FCP_DUMP: reipl_method = REIPL_METHOD_FCP_DUMP; break; case IPL_TYPE_NSS: - if (diag308_set_works) - reipl_method = REIPL_METHOD_NSS_DIAG; - else - reipl_method = REIPL_METHOD_NSS; + reipl_method = REIPL_METHOD_NSS_DIAG; set_reipl_block_actual(reipl_block_nss); break; case IPL_TYPE_UNKNOWN: @@ -1015,74 +980,22 @@ static struct kobj_attribute reipl_type_attr = static struct kset *reipl_kset; static struct kset *reipl_fcp_kset; -static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, - const enum ipl_method m) -{ - char loadparm[LOADPARM_LEN + 1] = {}; - char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; - char nss_name[NSS_NAME_SIZE + 1] = {}; - size_t pos = 0; - - reipl_get_ascii_loadparm(loadparm, ipb); - reipl_get_ascii_nss_name(nss_name, ipb); - reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); - - switch (m) { - case REIPL_METHOD_CCW_VM: - pos = sprintf(dst, "IPL %X CLEAR", ipb->ipl_info.ccw.devno); - break; - case REIPL_METHOD_NSS: - pos = sprintf(dst, "IPL %s", nss_name); - break; - default: - break; - } - if (strlen(loadparm) > 0) - pos += sprintf(dst + pos, " LOADPARM '%s'", loadparm); - if (strlen(vmparm) > 0) - sprintf(dst + pos, " PARM %s", vmparm); -} - static void __reipl_run(void *unused) { - struct ccw_dev_id devid; - static char buf[128]; - switch (reipl_method) { - case REIPL_METHOD_CCW_CIO: - devid.ssid = reipl_block_ccw->ipl_info.ccw.ssid; - devid.devno = reipl_block_ccw->ipl_info.ccw.devno; - reipl_ccw_dev(&devid); - break; - case REIPL_METHOD_CCW_VM: - get_ipl_string(buf, reipl_block_ccw, REIPL_METHOD_CCW_VM); - __cpcmd(buf, NULL, 0, NULL); - break; case REIPL_METHOD_CCW_DIAG: diag308(DIAG308_SET, reipl_block_ccw); diag308(DIAG308_LOAD_CLEAR, NULL); break; - case REIPL_METHOD_FCP_RW_DIAG: + case REIPL_METHOD_FCP_DIAG: diag308(DIAG308_SET, reipl_block_fcp); diag308(DIAG308_LOAD_CLEAR, NULL); break; - case REIPL_METHOD_FCP_RO_DIAG: - diag308(DIAG308_LOAD_CLEAR, NULL); - break; - case REIPL_METHOD_FCP_RO_VM: - __cpcmd("IPL", NULL, 0, NULL); - break; case REIPL_METHOD_NSS_DIAG: diag308(DIAG308_SET, reipl_block_nss); diag308(DIAG308_LOAD_CLEAR, NULL); break; - case REIPL_METHOD_NSS: - get_ipl_string(buf, reipl_block_nss, REIPL_METHOD_NSS); - __cpcmd(buf, NULL, 0, NULL); - break; case REIPL_METHOD_DEFAULT: - if (MACHINE_IS_VM) - __cpcmd("IPL", NULL, 0, NULL); diag308(DIAG308_LOAD_CLEAR, NULL); break; case REIPL_METHOD_FCP_DUMP: @@ -1138,9 +1051,6 @@ static int __init reipl_nss_init(void) if (!reipl_block_nss) return -ENOMEM; - if (!diag308_set_works) - sys_reipl_nss_vmparm_attr.attr.mode = S_IRUGO; - rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group); if (rc) return rc; @@ -1158,17 +1068,9 @@ static int __init reipl_ccw_init(void) if (!reipl_block_ccw) return -ENOMEM; - if (MACHINE_IS_VM) { - if (!diag308_set_works) - sys_reipl_ccw_vmparm_attr.attr.mode = S_IRUGO; - rc = sysfs_create_group(&reipl_kset->kobj, - &reipl_ccw_attr_group_vm); - } else { - if(!diag308_set_works) - sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; - rc = sysfs_create_group(&reipl_kset->kobj, - &reipl_ccw_attr_group_lpar); - } + rc = sysfs_create_group(&reipl_kset->kobj, + MACHINE_IS_VM ? &reipl_ccw_attr_group_vm + : &reipl_ccw_attr_group_lpar); if (rc) return rc; @@ -1187,14 +1089,6 @@ static int __init reipl_fcp_init(void) { int rc; - if (!diag308_set_works) { - if (ipl_info.type == IPL_TYPE_FCP) { - make_attrs_ro(reipl_fcp_attrs); - sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO; - } else - return 0; - } - reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); if (!reipl_block_fcp) return -ENOMEM; @@ -1339,12 +1233,7 @@ static int dump_set_type(enum dump_type type) return -EINVAL; switch (type) { case DUMP_TYPE_CCW: - if (diag308_set_works) - dump_method = DUMP_METHOD_CCW_DIAG; - else if (MACHINE_IS_VM) - dump_method = DUMP_METHOD_CCW_VM; - else - dump_method = DUMP_METHOD_CCW_CIO; + dump_method = DUMP_METHOD_CCW_DIAG; break; case DUMP_TYPE_FCP: dump_method = DUMP_METHOD_FCP_DIAG; @@ -1394,21 +1283,7 @@ static void diag308_dump(void *dump_block) static void __dump_run(void *unused) { - struct ccw_dev_id devid; - static char buf[100]; - switch (dump_method) { - case DUMP_METHOD_CCW_CIO: - devid.ssid = dump_block_ccw->ipl_info.ccw.ssid; - devid.devno = dump_block_ccw->ipl_info.ccw.devno; - reipl_ccw_dev(&devid); - break; - case DUMP_METHOD_CCW_VM: - sprintf(buf, "STORE STATUS"); - __cpcmd(buf, NULL, 0, NULL); - sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); - __cpcmd(buf, NULL, 0, NULL); - break; case DUMP_METHOD_CCW_DIAG: diag308_dump(dump_block_ccw); break; @@ -1454,8 +1329,6 @@ static int __init dump_fcp_init(void) if (!sclp_ipl_info.has_dump) return 0; /* LDIPL DUMP is not installed */ - if (!diag308_set_works) - return 0; dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); if (!dump_block_fcp) return -ENOMEM; @@ -1513,18 +1386,9 @@ static void dump_reipl_run(struct shutdown_trigger *trigger) dump_run(trigger); } -static int __init dump_reipl_init(void) -{ - if (!diag308_set_works) - return -EOPNOTSUPP; - else - return 0; -} - static struct shutdown_action __refdata dump_reipl_action = { .name = SHUTDOWN_ACTION_DUMP_REIPL_STR, .fn = dump_reipl_run, - .init = dump_reipl_init, }; /* @@ -1944,67 +1808,16 @@ void __init ipl_store_parameters(void) int rc; rc = diag308(DIAG308_STORE, &ipl_block); - if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG)) - diag308_set_works = 1; if (rc == DIAG308_RC_OK && ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION) ipl_block_valid = 1; } -static LIST_HEAD(rcall); -static DEFINE_MUTEX(rcall_mutex); - -void register_reset_call(struct reset_call *reset) -{ - mutex_lock(&rcall_mutex); - list_add(&reset->list, &rcall); - mutex_unlock(&rcall_mutex); -} -EXPORT_SYMBOL_GPL(register_reset_call); - -void unregister_reset_call(struct reset_call *reset) -{ - mutex_lock(&rcall_mutex); - list_del(&reset->list); - mutex_unlock(&rcall_mutex); -} -EXPORT_SYMBOL_GPL(unregister_reset_call); - -static void do_reset_calls(void) -{ - struct reset_call *reset; - - if (diag308_set_works) { - diag308_reset(); - return; - } - list_for_each_entry(reset, &rcall, list) - reset->fn(); -} - void s390_reset_system(void) { - struct lowcore *lc; - - lc = (struct lowcore *)(unsigned long) store_prefix(); - - /* Stack for interrupt/machine check handler */ - lc->panic_stack = S390_lowcore.panic_stack; - /* Disable prefixing */ set_prefix(0); /* Disable lowcore protection */ - __ctl_clear_bit(0,28); - - /* Set new machine check handler */ - S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT; - S390_lowcore.mcck_new_psw.addr = - (unsigned long) s390_base_mcck_handler; - - /* Set new program check handler */ - S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT; - S390_lowcore.program_new_psw.addr = - (unsigned long) s390_base_pgm_handler; - - do_reset_calls(); + __ctl_clear_bit(0, 28); + diag308_reset(); } diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index a80050bbe2e4..9adae2a1e1a0 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -20,7 +20,6 @@ #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/smp.h> -#include <asm/reset.h> #include <asm/ipl.h> #include <asm/diag.h> #include <asm/elf.h> diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index a40ebd1d29d0..73cc3750f0d3 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -75,90 +75,3 @@ ENTRY(store_status) .align 8 .Lclkcmp: .quad 0x0000000000000000 .previous - -# -# do_reipl_asm -# Parameter: r2 = schid of reipl device -# - -ENTRY(do_reipl_asm) - basr %r13,0 -.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) -.Lpg1: lgr %r3,%r2 - larl %r2,.Lstatus - brasl %r14,store_status - -.Lstatus: lctlg %c6,%c6,.Lall-.Lpg0(%r13) - lgr %r1,%r2 - mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) - stsch .Lschib-.Lpg0(%r13) - oi .Lschib+5-.Lpg0(%r13),0x84 -.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 - msch .Lschib-.Lpg0(%r13) - lghi %r0,5 -.Lssch: ssch .Liplorb-.Lpg0(%r13) - jz .L001 - brct %r0,.Lssch - bas %r14,.Ldisab-.Lpg0(%r13) -.L001: mvc __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13) -.Ltpi: lpswe .Lwaitpsw-.Lpg0(%r13) -.Lcont: c %r1,__LC_SUBCHANNEL_ID - jnz .Ltpi - clc __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13) - jnz .Ltpi - tsch .Liplirb-.Lpg0(%r13) - tm .Liplirb+9-.Lpg0(%r13),0xbf - jz .L002 - bas %r14,.Ldisab-.Lpg0(%r13) -.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 - jz .L003 - bas %r14,.Ldisab-.Lpg0(%r13) -.L003: st %r1,__LC_SUBCHANNEL_ID - lhi %r1,0 # mode 0 = esa - slr %r0,%r0 # set cpuid to zero - sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esa mode - lpsw 0 -.Ldisab: sll %r14,1 - srl %r14,1 # need to kill hi bit to avoid specification exceptions. - st %r14,.Ldispsw+12-.Lpg0(%r13) - lpswe .Ldispsw-.Lpg0(%r13) - .align 8 -.Lall: .quad 0x00000000ff000000 - .align 16 -/* - * These addresses have to be 31 bit otherwise - * the sigp will throw a specifcation exception - * when switching to ESA mode as bit 31 be set - * in the ESA psw. - * Bit 31 of the addresses has to be 0 for the - * 31bit lpswe instruction a fact they appear to have - * omitted from the pop. - */ -.Lnewpsw: .quad 0x0000000080000000 - .quad .Lpg1 -.Lpcnew: .quad 0x0000000080000000 - .quad .Lecs -.Lionew: .quad 0x0000000080000000 - .quad .Lcont -.Lwaitpsw: .quad 0x0202000080000000 - .quad .Ltpi -.Ldispsw: .quad 0x0002000080000000 - .quad 0x0000000000000000 -.Liplccws: .long 0x02000000,0x60000018 - .long 0x08000008,0x20000001 -.Liplorb: .long 0x0049504c,0x0040ff80 - .long 0x00000000+.Liplccws -.Lschib: .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 -.Liplirb: .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S index 9c2c96da23d0..c97c2d40fe15 100644 --- a/arch/s390/kernel/relocate_kernel.S +++ b/arch/s390/kernel/relocate_kernel.S @@ -29,33 +29,6 @@ ENTRY(relocate_kernel) basr %r13,0 # base address .base: - stctg %c0,%c15,ctlregs-.base(%r13) - stmg %r0,%r15,gprregs-.base(%r13) - lghi %r0,3 - sllg %r0,%r0,31 - stg %r0,0x1d0(%r0) - la %r0,.back_pgm-.base(%r13) - stg %r0,0x1d8(%r0) - la %r1,load_psw-.base(%r13) - mvc 0(8,%r0),0(%r1) - la %r0,.back-.base(%r13) - st %r0,4(%r0) - oi 4(%r0),0x80 - lghi %r0,0 - diag %r0,%r0,0x308 - .back: - lhi %r1,1 # mode 1 = esame - sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esame mode - sam64 # switch to 64 bit addressing mode - basr %r13,0 - .back_base: - oi have_diag308-.back_base(%r13),0x01 - lctlg %c0,%c15,ctlregs-.back_base(%r13) - lmg %r0,%r15,gprregs-.back_base(%r13) - j .top - .back_pgm: - lmg %r0,%r15,gprregs-.base(%r13) - .top: lghi %r7,PAGE_SIZE # load PAGE_SIZE in r7 lghi %r9,PAGE_SIZE # load PAGE_SIZE in r9 lg %r5,0(%r2) # read another word for indirection page @@ -64,55 +37,36 @@ ENTRY(relocate_kernel) je .indir_check # NO, goto "indir_check" lgr %r6,%r5 # r6 = r5 nill %r6,0xf000 # mask it out and... - j .top # ...next iteration + j .base # ...next iteration .indir_check: tml %r5,0x2 # is it a indirection page? je .done_test # NO, goto "done_test" nill %r5,0xf000 # YES, mask out, lgr %r2,%r5 # move it into the right register, - j .top # and read next... + j .base # and read next... .done_test: tml %r5,0x4 # is it the done indicator? je .source_test # NO! Well, then it should be the source indicator... j .done # ok, lets finish it here... .source_test: tml %r5,0x8 # it should be a source indicator... - je .top # NO, ignore it... + je .base # NO, ignore it... lgr %r8,%r5 # r8 = r5 nill %r8,0xf000 # masking 0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0 jo 0b - j .top + j .base .done: sgr %r0,%r0 # clear register r0 la %r4,load_psw-.base(%r13) # load psw-address into the register o %r3,4(%r4) # or load address into psw st %r3,4(%r4) mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0 - tm have_diag308-.base(%r13),0x01 - jno .no_diag308 diag %r0,%r0,0x308 - .no_diag308: - sam31 # 31 bit mode - sr %r1,%r1 # erase register r1 - sr %r2,%r2 # erase register r2 - sigp %r1,%r2,SIGP_SET_ARCHITECTURE # set cpuid to zero - lpsw 0 # hopefully start new kernel... .align 8 load_psw: .long 0x00080000,0x80000000 - ctlregs: - .rept 16 - .quad 0 - .endr - gprregs: - .rept 16 - .quad 0 - .endr - have_diag308: - .byte 0 - .align 8 relocate_kernel_end: .align 8 .globl relocate_kernel_len diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 28d4ee865a1c..5130d7c67239 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -25,7 +25,6 @@ #include <asm/irq.h> #include <asm/irq_regs.h> #include <asm/setup.h> -#include <asm/reset.h> #include <asm/ipl.h> #include <asm/chpid.h> #include <asm/airq.h> @@ -767,229 +766,6 @@ void cio_register_early_subchannels(void) } #endif /* CONFIG_CCW_CONSOLE */ -static int -__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) -{ - int retry, cc; - - cc = 0; - for (retry=0;retry<3;retry++) { - schib->pmcw.ena = 0; - cc = msch(schid, schib); - if (cc) - return (cc==3?-ENODEV:-EBUSY); - if (stsch(schid, schib) || !css_sch_is_valid(schib)) - return -ENODEV; - if (!schib->pmcw.ena) - return 0; - } - return -EBUSY; /* uhm... */ -} - -static int -__clear_io_subchannel_easy(struct subchannel_id schid) -{ - int retry; - - if (csch(schid)) - return -ENODEV; - for (retry=0;retry<20;retry++) { - struct tpi_info ti; - - if (tpi(&ti)) { - tsch(ti.schid, this_cpu_ptr(&cio_irb)); - if (schid_equal(&ti.schid, &schid)) - return 0; - } - udelay_simple(100); - } - return -EBUSY; -} - -static void __clear_chsc_subchannel_easy(void) -{ - /* It seems we can only wait for a bit here :/ */ - udelay_simple(100); -} - -static int pgm_check_occured; - -static void cio_reset_pgm_check_handler(void) -{ - pgm_check_occured = 1; -} - -static int stsch_reset(struct subchannel_id schid, struct schib *addr) -{ - int rc; - - pgm_check_occured = 0; - s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; - rc = stsch(schid, addr); - s390_base_pgm_handler_fn = NULL; - - /* The program check handler could have changed pgm_check_occured. */ - barrier(); - - if (pgm_check_occured) - return -EIO; - else - return rc; -} - -static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) -{ - struct schib schib; - - if (stsch_reset(schid, &schib)) - return -ENXIO; - if (!schib.pmcw.ena) - return 0; - switch(__disable_subchannel_easy(schid, &schib)) { - case 0: - case -ENODEV: - break; - default: /* -EBUSY */ - switch (schib.pmcw.st) { - case SUBCHANNEL_TYPE_IO: - if (__clear_io_subchannel_easy(schid)) - goto out; /* give up... */ - break; - case SUBCHANNEL_TYPE_CHSC: - __clear_chsc_subchannel_easy(); - break; - default: - /* No default clear strategy */ - break; - } - stsch(schid, &schib); - __disable_subchannel_easy(schid, &schib); - } -out: - return 0; -} - -static atomic_t chpid_reset_count; - -static void s390_reset_chpids_mcck_handler(void) -{ - struct crw crw; - union mci mci; - - /* Check for pending channel report word. */ - mci.val = S390_lowcore.mcck_interruption_code; - if (!mci.cp) - return; - /* Process channel report words. */ - while (stcrw(&crw) == 0) { - /* Check for responses to RCHP. */ - if (crw.slct && crw.rsc == CRW_RSC_CPATH) - atomic_dec(&chpid_reset_count); - } -} - -#define RCHP_TIMEOUT (30 * USEC_PER_SEC) -static void css_reset(void) -{ - int i, ret; - unsigned long long timeout; - struct chp_id chpid; - - /* Reset subchannels. */ - for_each_subchannel(__shutdown_subchannel_easy, NULL); - /* Reset channel paths. */ - s390_base_mcck_handler_fn = s390_reset_chpids_mcck_handler; - /* Enable channel report machine checks. */ - __ctl_set_bit(14, 28); - /* Temporarily reenable machine checks. */ - local_mcck_enable(); - chp_id_init(&chpid); - for (i = 0; i <= __MAX_CHPID; i++) { - chpid.id = i; - ret = rchp(chpid); - if ((ret == 0) || (ret == 2)) - /* - * rchp either succeeded, or another rchp is already - * in progress. In either case, we'll get a crw. - */ - atomic_inc(&chpid_reset_count); - } - /* Wait for machine check for all channel paths. */ - timeout = get_tod_clock_fast() + (RCHP_TIMEOUT << 12); - while (atomic_read(&chpid_reset_count) != 0) { - if (get_tod_clock_fast() > timeout) - break; - cpu_relax(); - } - /* Disable machine checks again. */ - local_mcck_disable(); - /* Disable channel report machine checks. */ - __ctl_clear_bit(14, 28); - s390_base_mcck_handler_fn = NULL; -} - -static struct reset_call css_reset_call = { - .fn = css_reset, -}; - -static int __init init_css_reset_call(void) -{ - atomic_set(&chpid_reset_count, 0); - register_reset_call(&css_reset_call); - return 0; -} - -arch_initcall(init_css_reset_call); - -struct sch_match_id { - struct subchannel_id schid; - struct ccw_dev_id devid; - int rc; -}; - -static int __reipl_subchannel_match(struct subchannel_id schid, void *data) -{ - struct schib schib; - struct sch_match_id *match_id = data; - - if (stsch_reset(schid, &schib)) - return -ENXIO; - if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && - (schib.pmcw.dev == match_id->devid.devno) && - (schid.ssid == match_id->devid.ssid)) { - match_id->schid = schid; - match_id->rc = 0; - return 1; - } - return 0; -} - -static int reipl_find_schid(struct ccw_dev_id *devid, - struct subchannel_id *schid) -{ - struct sch_match_id match_id; - - match_id.devid = *devid; - match_id.rc = -ENODEV; - for_each_subchannel(__reipl_subchannel_match, &match_id); - if (match_id.rc == 0) - *schid = match_id.schid; - return match_id.rc; -} - -extern void do_reipl_asm(__u32 schid); - -/* Make sure all subchannels are quiet before we re-ipl an lpar. */ -void reipl_ccw_dev(struct ccw_dev_id *devid) -{ - struct subchannel_id uninitialized_var(schid); - - s390_reset_system(); - if (reipl_find_schid(devid, &schid) != 0) - panic("IPL Device not found\n"); - do_reipl_asm(*((__u32*)&schid)); -} - /** * cio_tm_start_key - perform start function * @sch: subchannel on which to perform the start function diff --git a/drivers/s390/cio/ioasm.c b/drivers/s390/cio/ioasm.c index 4fa9ee1d09fa..14d328338ce2 100644 --- a/drivers/s390/cio/ioasm.c +++ b/drivers/s390/cio/ioasm.c @@ -183,30 +183,6 @@ int chsc(void *chsc_area) } EXPORT_SYMBOL(chsc); -static inline int __rchp(struct chp_id chpid) -{ - register struct chp_id reg1 asm ("1") = chpid; - int ccode; - - asm volatile( - " lr 1,%1\n" - " rchp\n" - " ipm %0\n" - " srl %0,28" - : "=d" (ccode) : "d" (reg1) : "cc"); - return ccode; -} - -int rchp(struct chp_id chpid) -{ - int ccode; - - ccode = __rchp(chpid); - trace_s390_cio_rchp(chpid, ccode); - - return ccode; -} - static inline int __rsch(struct subchannel_id schid) { register struct subchannel_id reg1 asm("1") = schid; diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index 35ad4ddd61e0..4be539cb9adc 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h @@ -20,7 +20,6 @@ int ssch(struct subchannel_id schid, union orb *addr); int csch(struct subchannel_id schid); int tpi(struct tpi_info *addr); int chsc(void *chsc_area); -int rchp(struct chp_id chpid); int rsch(struct subchannel_id schid); int hsch(struct subchannel_id schid); int xsch(struct subchannel_id schid); diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 743594e61da4..dfed422954b4 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -25,7 +25,6 @@ #include <linux/kthread.h> #include <linux/mutex.h> #include <linux/suspend.h> -#include <asm/reset.h> #include <asm/airq.h> #include <linux/atomic.h> #include <asm/isc.h> @@ -1197,25 +1196,6 @@ static void ap_config_timeout(struct timer_list *unused) queue_work(system_long_wq, &ap_scan_work); } -static void ap_reset_all(void) -{ - int i, j; - - for (i = 0; i < AP_DOMAINS; i++) { - if (!ap_test_config_domain(i)) - continue; - for (j = 0; j < AP_DEVICES; j++) { - if (!ap_test_config_card_id(j)) - continue; - ap_rapq(AP_MKQID(j, i)); - } - } -} - -static struct reset_call ap_reset_call = { - .fn = ap_reset_all, -}; - int __init ap_debug_init(void) { ap_dbf_info = debug_register("ap", 1, 1, @@ -1269,8 +1249,6 @@ int __init ap_module_init(void) ap_airq_flag = (rc == 0); } - register_reset_call(&ap_reset_call); - /* Create /sys/bus/ap. */ rc = bus_register(&ap_bus_type); if (rc) @@ -1326,7 +1304,6 @@ out_bus: bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); bus_unregister(&ap_bus_type); out: - unregister_reset_call(&ap_reset_call); if (ap_using_interrupts()) unregister_adapter_interrupt(&ap_airq); kfree(ap_configuration); |