aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/Kconfig21
-rw-r--r--arch/s390/Kconfig.debug3
-rw-r--r--arch/s390/Makefile3
-rw-r--r--arch/s390/boot/compressed/Makefile6
-rw-r--r--arch/s390/boot/compressed/misc.c5
-rw-r--r--arch/s390/include/asm/cacheflush.h4
-rw-r--r--arch/s390/kernel/machine_kexec.c2
-rw-r--r--arch/s390/mm/Makefile1
-rw-r--r--arch/s390/mm/pageattr.c55
-rw-r--r--drivers/s390/block/dasd_eckd.c1
-rw-r--r--drivers/s390/cio/chsc_sch.c17
-rw-r--r--drivers/s390/cio/cio.c43
-rw-r--r--drivers/s390/cio/cio.h11
-rw-r--r--drivers/s390/cio/css.c6
-rw-r--r--drivers/s390/cio/css.h10
-rw-r--r--drivers/s390/cio/device.c23
-rw-r--r--drivers/s390/cio/io_sch.h114
-rw-r--r--drivers/s390/cio/ioasm.h34
-rw-r--r--drivers/s390/cio/orb.h67
19 files changed, 248 insertions, 178 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 636bcb81d068..2508a6f31588 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -85,6 +85,7 @@ config S390
85 select HAVE_KERNEL_BZIP2 85 select HAVE_KERNEL_BZIP2
86 select HAVE_KERNEL_LZMA 86 select HAVE_KERNEL_LZMA
87 select HAVE_KERNEL_LZO 87 select HAVE_KERNEL_LZO
88 select HAVE_KERNEL_XZ
88 select HAVE_GET_USER_PAGES_FAST 89 select HAVE_GET_USER_PAGES_FAST
89 select HAVE_ARCH_MUTEX_CPU_RELAX 90 select HAVE_ARCH_MUTEX_CPU_RELAX
90 select ARCH_INLINE_SPIN_TRYLOCK 91 select ARCH_INLINE_SPIN_TRYLOCK
@@ -341,26 +342,16 @@ config STACK_GUARD
341 The minimum size for the stack guard should be 256 for 31 bit and 342 The minimum size for the stack guard should be 256 for 31 bit and
342 512 for 64 bit. 343 512 for 64 bit.
343 344
344config WARN_STACK 345config WARN_DYNAMIC_STACK
345 def_bool n 346 def_bool n
346 prompt "Emit compiler warnings for function with broken stack usage" 347 prompt "Emit compiler warnings for function with dynamic stack usage"
347 help 348 help
348 This option enables the compiler options -mwarn-framesize and 349 This option enables the compiler option -mwarn-dynamicstack. If the
349 -mwarn-dynamicstack. If the compiler supports these options it 350 compiler supports this options generates warnings for functions
350 will generate warnings for function which either use alloca or 351 that dynamically allocate stack space using alloca.
351 create a stack frame bigger than CONFIG_WARN_STACK_SIZE.
352 352
353 Say N if you are unsure. 353 Say N if you are unsure.
354 354
355config WARN_STACK_SIZE
356 int "Maximum frame size considered safe (128-2048)"
357 range 128 2048
358 depends on WARN_STACK
359 default "2048"
360 help
361 This allows you to specify the maximum frame size a function may
362 have without the compiler complaining about it.
363
364config ARCH_POPULATES_NODE_MAP 355config ARCH_POPULATES_NODE_MAP
365 def_bool y 356 def_bool y
366 357
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index 2b380df95606..d76cef3fef37 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -31,4 +31,7 @@ config DEBUG_STRICT_USER_COPY_CHECKS
31 31
32 If unsure, or if you run an older (pre 4.4) gcc, say N. 32 If unsure, or if you run an older (pre 4.4) gcc, say N.
33 33
34config DEBUG_SET_MODULE_RONX
35 def_bool y
36 depends on MODULES
34endmenu 37endmenu
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index d5b8a6ade525..27a0b5df5ead 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -80,8 +80,7 @@ endif
80endif 80endif
81 81
82ifeq ($(call cc-option-yn,-mwarn-dynamicstack),y) 82ifeq ($(call cc-option-yn,-mwarn-dynamicstack),y)
83cflags-$(CONFIG_WARN_STACK) += -mwarn-dynamicstack 83cflags-$(CONFIG_WARN_DYNAMIC_STACK) += -mwarn-dynamicstack
84cflags-$(CONFIG_WARN_STACK) += -mwarn-framesize=$(CONFIG_WARN_STACK_SIZE)
85endif 84endif
86 85
87KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y) 86KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y)
diff --git a/arch/s390/boot/compressed/Makefile b/arch/s390/boot/compressed/Makefile
index 1c999f726a58..10e22c4ec4a7 100644
--- a/arch/s390/boot/compressed/Makefile
+++ b/arch/s390/boot/compressed/Makefile
@@ -7,7 +7,8 @@
7BITS := $(if $(CONFIG_64BIT),64,31) 7BITS := $(if $(CONFIG_64BIT),64,31)
8 8
9targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \ 9targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
10 vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o sizes.h head$(BITS).o 10 vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o \
11 sizes.h head$(BITS).o
11 12
12KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 13KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
13KBUILD_CFLAGS += $(cflags-y) 14KBUILD_CFLAGS += $(cflags-y)
@@ -48,6 +49,7 @@ suffix-$(CONFIG_KERNEL_GZIP) := gz
48suffix-$(CONFIG_KERNEL_BZIP2) := bz2 49suffix-$(CONFIG_KERNEL_BZIP2) := bz2
49suffix-$(CONFIG_KERNEL_LZMA) := lzma 50suffix-$(CONFIG_KERNEL_LZMA) := lzma
50suffix-$(CONFIG_KERNEL_LZO) := lzo 51suffix-$(CONFIG_KERNEL_LZO) := lzo
52suffix-$(CONFIG_KERNEL_XZ) := xz
51 53
52$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) 54$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
53 $(call if_changed,gzip) 55 $(call if_changed,gzip)
@@ -57,6 +59,8 @@ $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
57 $(call if_changed,lzma) 59 $(call if_changed,lzma)
58$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) 60$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
59 $(call if_changed,lzo) 61 $(call if_changed,lzo)
62$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y)
63 $(call if_changed,xzkern)
60 64
61LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T 65LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
62$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) 66$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c
index 2751b3a8a66f..028f23ea81d1 100644
--- a/arch/s390/boot/compressed/misc.c
+++ b/arch/s390/boot/compressed/misc.c
@@ -19,6 +19,7 @@
19#undef memset 19#undef memset
20#undef memcpy 20#undef memcpy
21#undef memmove 21#undef memmove
22#define memmove memmove
22#define memzero(s, n) memset((s), 0, (n)) 23#define memzero(s, n) memset((s), 0, (n))
23 24
24/* Symbols defined by linker scripts */ 25/* Symbols defined by linker scripts */
@@ -54,6 +55,10 @@ static unsigned long free_mem_end_ptr;
54#include "../../../../lib/decompress_unlzo.c" 55#include "../../../../lib/decompress_unlzo.c"
55#endif 56#endif
56 57
58#ifdef CONFIG_KERNEL_XZ
59#include "../../../../lib/decompress_unxz.c"
60#endif
61
57extern _sclp_print_early(const char *); 62extern _sclp_print_early(const char *);
58 63
59int puts(const char *s) 64int puts(const char *s)
diff --git a/arch/s390/include/asm/cacheflush.h b/arch/s390/include/asm/cacheflush.h
index 7e1f77620624..43a5c78046db 100644
--- a/arch/s390/include/asm/cacheflush.h
+++ b/arch/s390/include/asm/cacheflush.h
@@ -8,4 +8,8 @@
8void kernel_map_pages(struct page *page, int numpages, int enable); 8void kernel_map_pages(struct page *page, int numpages, int enable);
9#endif 9#endif
10 10
11int set_memory_ro(unsigned long addr, int numpages);
12int set_memory_rw(unsigned long addr, int numpages);
13int set_memory_nx(unsigned long addr, int numpages);
14
11#endif /* _S390_CACHEFLUSH_H */ 15#endif /* _S390_CACHEFLUSH_H */
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index a922d51df6bf..b09b9c62573e 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -12,6 +12,7 @@
12#include <linux/kexec.h> 12#include <linux/kexec.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/reboot.h> 14#include <linux/reboot.h>
15#include <linux/ftrace.h>
15#include <asm/cio.h> 16#include <asm/cio.h>
16#include <asm/setup.h> 17#include <asm/setup.h>
17#include <asm/pgtable.h> 18#include <asm/pgtable.h>
@@ -71,6 +72,7 @@ static void __machine_kexec(void *data)
71 72
72void machine_kexec(struct kimage *image) 73void machine_kexec(struct kimage *image)
73{ 74{
75 tracer_disable();
74 smp_send_stop(); 76 smp_send_stop();
75 smp_switch_to_ipl_cpu(__machine_kexec, image); 77 smp_switch_to_ipl_cpu(__machine_kexec, image);
76} 78}
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index 6fbc6f3fbdf2..d98fe9004a52 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -6,3 +6,4 @@ obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \
6 page-states.o gup.o 6 page-states.o gup.o
7obj-$(CONFIG_CMM) += cmm.o 7obj-$(CONFIG_CMM) += cmm.o
8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 8obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
9obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
new file mode 100644
index 000000000000..122ffbd08ce0
--- /dev/null
+++ b/arch/s390/mm/pageattr.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright IBM Corp. 2011
3 * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
4 */
5#include <linux/module.h>
6#include <linux/mm.h>
7#include <linux/hugetlb.h>
8#include <asm/pgtable.h>
9
10static void change_page_attr(unsigned long addr, int numpages,
11 pte_t (*set) (pte_t))
12{
13 pte_t *ptep, pte;
14 pmd_t *pmdp;
15 pud_t *pudp;
16 pgd_t *pgdp;
17 int i;
18
19 for (i = 0; i < numpages; i++) {
20 pgdp = pgd_offset(&init_mm, addr);
21 pudp = pud_offset(pgdp, addr);
22 pmdp = pmd_offset(pudp, addr);
23 if (pmd_huge(*pmdp)) {
24 WARN_ON_ONCE(1);
25 continue;
26 }
27 ptep = pte_offset_kernel(pmdp, addr + i * PAGE_SIZE);
28
29 pte = *ptep;
30 pte = set(pte);
31 ptep_invalidate(&init_mm, addr + i * PAGE_SIZE, ptep);
32 *ptep = pte;
33 }
34}
35
36int set_memory_ro(unsigned long addr, int numpages)
37{
38 change_page_attr(addr, numpages, pte_wrprotect);
39 return 0;
40}
41EXPORT_SYMBOL_GPL(set_memory_ro);
42
43int set_memory_rw(unsigned long addr, int numpages)
44{
45 change_page_attr(addr, numpages, pte_mkwrite);
46 return 0;
47}
48EXPORT_SYMBOL_GPL(set_memory_rw);
49
50/* not possible */
51int set_memory_nx(unsigned long addr, int numpages)
52{
53 return 0;
54}
55EXPORT_SYMBOL_GPL(set_memory_nx);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index a9fe23d5bd0f..379d8592bc6e 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2648,6 +2648,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2648 dasd_sfree_request(cqr, startdev); 2648 dasd_sfree_request(cqr, startdev);
2649 return ERR_PTR(-EAGAIN); 2649 return ERR_PTR(-EAGAIN);
2650 } 2650 }
2651 len_to_track_end = 0;
2651 /* 2652 /*
2652 * A tidaw can address 4k of memory, but must not cross page boundaries 2653 * A tidaw can address 4k of memory, but must not cross page boundaries
2653 * We can let the block layer handle this by setting 2654 * We can let the block layer handle this by setting
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 3c3f3ffe2179..e950f1ad4dd1 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -50,7 +50,7 @@ MODULE_LICENSE("GPL");
50 50
51static void chsc_subchannel_irq(struct subchannel *sch) 51static void chsc_subchannel_irq(struct subchannel *sch)
52{ 52{
53 struct chsc_private *private = sch->private; 53 struct chsc_private *private = dev_get_drvdata(&sch->dev);
54 struct chsc_request *request = private->request; 54 struct chsc_request *request = private->request;
55 struct irb *irb = (struct irb *)&S390_lowcore.irb; 55 struct irb *irb = (struct irb *)&S390_lowcore.irb;
56 56
@@ -80,13 +80,14 @@ static int chsc_subchannel_probe(struct subchannel *sch)
80 private = kzalloc(sizeof(*private), GFP_KERNEL); 80 private = kzalloc(sizeof(*private), GFP_KERNEL);
81 if (!private) 81 if (!private)
82 return -ENOMEM; 82 return -ENOMEM;
83 dev_set_drvdata(&sch->dev, private);
83 ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); 84 ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch);
84 if (ret) { 85 if (ret) {
85 CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n", 86 CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n",
86 sch->schid.ssid, sch->schid.sch_no, ret); 87 sch->schid.ssid, sch->schid.sch_no, ret);
88 dev_set_drvdata(&sch->dev, NULL);
87 kfree(private); 89 kfree(private);
88 } else { 90 } else {
89 sch->private = private;
90 if (dev_get_uevent_suppress(&sch->dev)) { 91 if (dev_get_uevent_suppress(&sch->dev)) {
91 dev_set_uevent_suppress(&sch->dev, 0); 92 dev_set_uevent_suppress(&sch->dev, 0);
92 kobject_uevent(&sch->dev.kobj, KOBJ_ADD); 93 kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
@@ -100,8 +101,8 @@ static int chsc_subchannel_remove(struct subchannel *sch)
100 struct chsc_private *private; 101 struct chsc_private *private;
101 102
102 cio_disable_subchannel(sch); 103 cio_disable_subchannel(sch);
103 private = sch->private; 104 private = dev_get_drvdata(&sch->dev);
104 sch->private = NULL; 105 dev_set_drvdata(&sch->dev, NULL);
105 if (private->request) { 106 if (private->request) {
106 complete(&private->request->completion); 107 complete(&private->request->completion);
107 put_device(&sch->dev); 108 put_device(&sch->dev);
@@ -147,7 +148,10 @@ static struct css_device_id chsc_subchannel_ids[] = {
147MODULE_DEVICE_TABLE(css, chsc_subchannel_ids); 148MODULE_DEVICE_TABLE(css, chsc_subchannel_ids);
148 149
149static struct css_driver chsc_subchannel_driver = { 150static struct css_driver chsc_subchannel_driver = {
150 .owner = THIS_MODULE, 151 .drv = {
152 .owner = THIS_MODULE,
153 .name = "chsc_subchannel",
154 },
151 .subchannel_type = chsc_subchannel_ids, 155 .subchannel_type = chsc_subchannel_ids,
152 .irq = chsc_subchannel_irq, 156 .irq = chsc_subchannel_irq,
153 .probe = chsc_subchannel_probe, 157 .probe = chsc_subchannel_probe,
@@ -157,7 +161,6 @@ static struct css_driver chsc_subchannel_driver = {
157 .freeze = chsc_subchannel_freeze, 161 .freeze = chsc_subchannel_freeze,
158 .thaw = chsc_subchannel_restore, 162 .thaw = chsc_subchannel_restore,
159 .restore = chsc_subchannel_restore, 163 .restore = chsc_subchannel_restore,
160 .name = "chsc_subchannel",
161}; 164};
162 165
163static int __init chsc_init_dbfs(void) 166static int __init chsc_init_dbfs(void)
@@ -241,7 +244,7 @@ static int chsc_async(struct chsc_async_area *chsc_area,
241 chsc_area->header.key = PAGE_DEFAULT_KEY >> 4; 244 chsc_area->header.key = PAGE_DEFAULT_KEY >> 4;
242 while ((sch = chsc_get_next_subchannel(sch))) { 245 while ((sch = chsc_get_next_subchannel(sch))) {
243 spin_lock(sch->lock); 246 spin_lock(sch->lock);
244 private = sch->private; 247 private = dev_get_drvdata(&sch->dev);
245 if (private->request) { 248 if (private->request) {
246 spin_unlock(sch->lock); 249 spin_unlock(sch->lock);
247 ret = -EBUSY; 250 ret = -EBUSY;
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 430f875006f2..cbde448f9947 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -84,29 +84,14 @@ out_unregister:
84 84
85arch_initcall (cio_debug_init); 85arch_initcall (cio_debug_init);
86 86
87int 87int cio_set_options(struct subchannel *sch, int flags)
88cio_set_options (struct subchannel *sch, int flags)
89{ 88{
90 sch->options.suspend = (flags & DOIO_ALLOW_SUSPEND) != 0; 89 struct io_subchannel_private *priv = to_io_private(sch);
91 sch->options.prefetch = (flags & DOIO_DENY_PREFETCH) != 0;
92 sch->options.inter = (flags & DOIO_SUPPRESS_INTER) != 0;
93 return 0;
94}
95 90
96/* FIXME: who wants to use this? */ 91 priv->options.suspend = (flags & DOIO_ALLOW_SUSPEND) != 0;
97int 92 priv->options.prefetch = (flags & DOIO_DENY_PREFETCH) != 0;
98cio_get_options (struct subchannel *sch) 93 priv->options.inter = (flags & DOIO_SUPPRESS_INTER) != 0;
99{ 94 return 0;
100 int flags;
101
102 flags = 0;
103 if (sch->options.suspend)
104 flags |= DOIO_ALLOW_SUSPEND;
105 if (sch->options.prefetch)
106 flags |= DOIO_DENY_PREFETCH;
107 if (sch->options.inter)
108 flags |= DOIO_SUPPRESS_INTER;
109 return flags;
110} 95}
111 96
112static int 97static int
@@ -139,21 +124,21 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
139 __u8 lpm, /* logical path mask */ 124 __u8 lpm, /* logical path mask */
140 __u8 key) /* storage key */ 125 __u8 key) /* storage key */
141{ 126{
127 struct io_subchannel_private *priv = to_io_private(sch);
128 union orb *orb = &priv->orb;
142 int ccode; 129 int ccode;
143 union orb *orb;
144 130
145 CIO_TRACE_EVENT(5, "stIO"); 131 CIO_TRACE_EVENT(5, "stIO");
146 CIO_TRACE_EVENT(5, dev_name(&sch->dev)); 132 CIO_TRACE_EVENT(5, dev_name(&sch->dev));
147 133
148 orb = &to_io_private(sch)->orb;
149 memset(orb, 0, sizeof(union orb)); 134 memset(orb, 0, sizeof(union orb));
150 /* sch is always under 2G. */ 135 /* sch is always under 2G. */
151 orb->cmd.intparm = (u32)(addr_t)sch; 136 orb->cmd.intparm = (u32)(addr_t)sch;
152 orb->cmd.fmt = 1; 137 orb->cmd.fmt = 1;
153 138
154 orb->cmd.pfch = sch->options.prefetch == 0; 139 orb->cmd.pfch = priv->options.prefetch == 0;
155 orb->cmd.spnd = sch->options.suspend; 140 orb->cmd.spnd = priv->options.suspend;
156 orb->cmd.ssic = sch->options.suspend && sch->options.inter; 141 orb->cmd.ssic = priv->options.suspend && priv->options.inter;
157 orb->cmd.lpm = (lpm != 0) ? lpm : sch->lpm; 142 orb->cmd.lpm = (lpm != 0) ? lpm : sch->lpm;
158#ifdef CONFIG_64BIT 143#ifdef CONFIG_64BIT
159 /* 144 /*
@@ -630,11 +615,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
630 irb = (struct irb *)&S390_lowcore.irb; 615 irb = (struct irb *)&S390_lowcore.irb;
631 do { 616 do {
632 kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++; 617 kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++;
633 /* 618 if (tpi_info->adapter_IO) {
634 * Non I/O-subchannel thin interrupts are processed differently
635 */
636 if (tpi_info->adapter_IO == 1 &&
637 tpi_info->int_type == IO_INTERRUPT_TYPE) {
638 do_adapter_IO(tpi_info->isc); 619 do_adapter_IO(tpi_info->isc);
639 continue; 620 continue;
640 } 621 }
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index bf7f80f5a330..155a82bcb9e5 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -84,13 +84,6 @@ struct subchannel {
84 SUBCHANNEL_TYPE_MSG = 2, 84 SUBCHANNEL_TYPE_MSG = 2,
85 SUBCHANNEL_TYPE_ADM = 3, 85 SUBCHANNEL_TYPE_ADM = 3,
86 } st; /* subchannel type */ 86 } st; /* subchannel type */
87
88 struct {
89 unsigned int suspend:1; /* allow suspend */
90 unsigned int prefetch:1;/* deny prefetch */
91 unsigned int inter:1; /* suppress intermediate interrupts */
92 } __attribute__ ((packed)) options;
93
94 __u8 vpm; /* verified path mask */ 87 __u8 vpm; /* verified path mask */
95 __u8 lpm; /* logical path mask */ 88 __u8 lpm; /* logical path mask */
96 __u8 opm; /* operational path mask */ 89 __u8 opm; /* operational path mask */
@@ -99,14 +92,11 @@ struct subchannel {
99 struct chsc_ssd_info ssd_info; /* subchannel description */ 92 struct chsc_ssd_info ssd_info; /* subchannel description */
100 struct device dev; /* entry in device tree */ 93 struct device dev; /* entry in device tree */
101 struct css_driver *driver; 94 struct css_driver *driver;
102 void *private; /* private per subchannel type data */
103 enum sch_todo todo; 95 enum sch_todo todo;
104 struct work_struct todo_work; 96 struct work_struct todo_work;
105 struct schib_config config; 97 struct schib_config config;
106} __attribute__ ((aligned(8))); 98} __attribute__ ((aligned(8)));
107 99
108#define IO_INTERRUPT_TYPE 0 /* I/O interrupt type */
109
110#define to_subchannel(n) container_of(n, struct subchannel, dev) 100#define to_subchannel(n) container_of(n, struct subchannel, dev)
111 101
112extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); 102extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id);
@@ -120,7 +110,6 @@ extern int cio_start (struct subchannel *, struct ccw1 *, __u8);
120extern int cio_start_key (struct subchannel *, struct ccw1 *, __u8, __u8); 110extern int cio_start_key (struct subchannel *, struct ccw1 *, __u8, __u8);
121extern int cio_cancel (struct subchannel *); 111extern int cio_cancel (struct subchannel *);
122extern int cio_set_options (struct subchannel *, int); 112extern int cio_set_options (struct subchannel *, int);
123extern int cio_get_options (struct subchannel *);
124extern int cio_update_schib(struct subchannel *sch); 113extern int cio_update_schib(struct subchannel *sch);
125extern int cio_commit_config(struct subchannel *sch); 114extern int cio_commit_config(struct subchannel *sch);
126 115
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 24d8e97355b9..c47b25fd3f43 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -35,6 +35,7 @@ int css_init_done = 0;
35int max_ssid; 35int max_ssid;
36 36
37struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; 37struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1];
38static struct bus_type css_bus_type;
38 39
39int 40int
40for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data) 41for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
@@ -1214,7 +1215,7 @@ static const struct dev_pm_ops css_pm_ops = {
1214 .restore = css_pm_restore, 1215 .restore = css_pm_restore,
1215}; 1216};
1216 1217
1217struct bus_type css_bus_type = { 1218static struct bus_type css_bus_type = {
1218 .name = "css", 1219 .name = "css",
1219 .match = css_bus_match, 1220 .match = css_bus_match,
1220 .probe = css_probe, 1221 .probe = css_probe,
@@ -1233,9 +1234,7 @@ struct bus_type css_bus_type = {
1233 */ 1234 */
1234int css_driver_register(struct css_driver *cdrv) 1235int css_driver_register(struct css_driver *cdrv)
1235{ 1236{
1236 cdrv->drv.name = cdrv->name;
1237 cdrv->drv.bus = &css_bus_type; 1237 cdrv->drv.bus = &css_bus_type;
1238 cdrv->drv.owner = cdrv->owner;
1239 return driver_register(&cdrv->drv); 1238 return driver_register(&cdrv->drv);
1240} 1239}
1241EXPORT_SYMBOL_GPL(css_driver_register); 1240EXPORT_SYMBOL_GPL(css_driver_register);
@@ -1253,4 +1252,3 @@ void css_driver_unregister(struct css_driver *cdrv)
1253EXPORT_SYMBOL_GPL(css_driver_unregister); 1252EXPORT_SYMBOL_GPL(css_driver_unregister);
1254 1253
1255MODULE_LICENSE("GPL"); 1254MODULE_LICENSE("GPL");
1256EXPORT_SYMBOL(css_bus_type);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 7e37886de231..80ebdddf7747 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -63,7 +63,6 @@ struct subchannel;
63struct chp_link; 63struct chp_link;
64/** 64/**
65 * struct css_driver - device driver for subchannels 65 * struct css_driver - device driver for subchannels
66 * @owner: owning module
67 * @subchannel_type: subchannel type supported by this driver 66 * @subchannel_type: subchannel type supported by this driver
68 * @drv: embedded device driver structure 67 * @drv: embedded device driver structure
69 * @irq: called on interrupts 68 * @irq: called on interrupts
@@ -78,10 +77,8 @@ struct chp_link;
78 * @thaw: undo work done in @freeze 77 * @thaw: undo work done in @freeze
79 * @restore: callback for restoring after hibernation 78 * @restore: callback for restoring after hibernation
80 * @settle: wait for asynchronous work to finish 79 * @settle: wait for asynchronous work to finish
81 * @name: name of the device driver
82 */ 80 */
83struct css_driver { 81struct css_driver {
84 struct module *owner;
85 struct css_device_id *subchannel_type; 82 struct css_device_id *subchannel_type;
86 struct device_driver drv; 83 struct device_driver drv;
87 void (*irq)(struct subchannel *); 84 void (*irq)(struct subchannel *);
@@ -96,16 +93,10 @@ struct css_driver {
96 int (*thaw) (struct subchannel *); 93 int (*thaw) (struct subchannel *);
97 int (*restore)(struct subchannel *); 94 int (*restore)(struct subchannel *);
98 int (*settle)(void); 95 int (*settle)(void);
99 const char *name;
100}; 96};
101 97
102#define to_cssdriver(n) container_of(n, struct css_driver, drv) 98#define to_cssdriver(n) container_of(n, struct css_driver, drv)
103 99
104/*
105 * all css_drivers have the css_bus_type
106 */
107extern struct bus_type css_bus_type;
108
109extern int css_driver_register(struct css_driver *); 100extern int css_driver_register(struct css_driver *);
110extern void css_driver_unregister(struct css_driver *); 101extern void css_driver_unregister(struct css_driver *);
111 102
@@ -140,7 +131,6 @@ struct channel_subsystem {
140}; 131};
141#define to_css(dev) container_of(dev, struct channel_subsystem, device) 132#define to_css(dev) container_of(dev, struct channel_subsystem, device)
142 133
143extern struct bus_type css_bus_type;
144extern struct channel_subsystem *channel_subsystems[]; 134extern struct channel_subsystem *channel_subsystems[];
145 135
146/* Helper functions to build lists for the slow path. */ 136/* Helper functions to build lists for the slow path. */
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index b7eaff9ca19e..e50b12163afe 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -172,9 +172,11 @@ static int io_subchannel_settle(void)
172} 172}
173 173
174static struct css_driver io_subchannel_driver = { 174static struct css_driver io_subchannel_driver = {
175 .owner = THIS_MODULE, 175 .drv = {
176 .owner = THIS_MODULE,
177 .name = "io_subchannel",
178 },
176 .subchannel_type = io_subchannel_ids, 179 .subchannel_type = io_subchannel_ids,
177 .name = "io_subchannel",
178 .irq = io_subchannel_irq, 180 .irq = io_subchannel_irq,
179 .sch_event = io_subchannel_sch_event, 181 .sch_event = io_subchannel_sch_event,
180 .chp_event = io_subchannel_chp_event, 182 .chp_event = io_subchannel_chp_event,
@@ -1030,6 +1032,7 @@ static void io_subchannel_init_fields(struct subchannel *sch)
1030 */ 1032 */
1031static int io_subchannel_probe(struct subchannel *sch) 1033static int io_subchannel_probe(struct subchannel *sch)
1032{ 1034{
1035 struct io_subchannel_private *io_priv;
1033 struct ccw_device *cdev; 1036 struct ccw_device *cdev;
1034 int rc; 1037 int rc;
1035 1038
@@ -1073,10 +1076,11 @@ static int io_subchannel_probe(struct subchannel *sch)
1073 if (rc) 1076 if (rc)
1074 goto out_schedule; 1077 goto out_schedule;
1075 /* Allocate I/O subchannel private data. */ 1078 /* Allocate I/O subchannel private data. */
1076 sch->private = kzalloc(sizeof(struct io_subchannel_private), 1079 io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA);
1077 GFP_KERNEL | GFP_DMA); 1080 if (!io_priv)
1078 if (!sch->private)
1079 goto out_schedule; 1081 goto out_schedule;
1082
1083 set_io_private(sch, io_priv);
1080 css_schedule_eval(sch->schid); 1084 css_schedule_eval(sch->schid);
1081 return 0; 1085 return 0;
1082 1086
@@ -1090,6 +1094,7 @@ out_schedule:
1090static int 1094static int
1091io_subchannel_remove (struct subchannel *sch) 1095io_subchannel_remove (struct subchannel *sch)
1092{ 1096{
1097 struct io_subchannel_private *io_priv = to_io_private(sch);
1093 struct ccw_device *cdev; 1098 struct ccw_device *cdev;
1094 1099
1095 cdev = sch_get_cdev(sch); 1100 cdev = sch_get_cdev(sch);
@@ -1099,11 +1104,12 @@ io_subchannel_remove (struct subchannel *sch)
1099 /* Set ccw device to not operational and drop reference. */ 1104 /* Set ccw device to not operational and drop reference. */
1100 spin_lock_irq(cdev->ccwlock); 1105 spin_lock_irq(cdev->ccwlock);
1101 sch_set_cdev(sch, NULL); 1106 sch_set_cdev(sch, NULL);
1107 set_io_private(sch, NULL);
1102 cdev->private->state = DEV_STATE_NOT_OPER; 1108 cdev->private->state = DEV_STATE_NOT_OPER;
1103 spin_unlock_irq(cdev->ccwlock); 1109 spin_unlock_irq(cdev->ccwlock);
1104 ccw_device_unregister(cdev); 1110 ccw_device_unregister(cdev);
1105out_free: 1111out_free:
1106 kfree(sch->private); 1112 kfree(io_priv);
1107 sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); 1113 sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
1108 return 0; 1114 return 0;
1109} 1115}
@@ -1553,11 +1559,12 @@ spinlock_t * cio_get_console_lock(void)
1553static int ccw_device_console_enable(struct ccw_device *cdev, 1559static int ccw_device_console_enable(struct ccw_device *cdev,
1554 struct subchannel *sch) 1560 struct subchannel *sch)
1555{ 1561{
1562 struct io_subchannel_private *io_priv = cio_get_console_priv();
1556 int rc; 1563 int rc;
1557 1564
1558 /* Attach subchannel private data. */ 1565 /* Attach subchannel private data. */
1559 sch->private = cio_get_console_priv(); 1566 memset(io_priv, 0, sizeof(*io_priv));
1560 memset(sch->private, 0, sizeof(struct io_subchannel_private)); 1567 set_io_private(sch, io_priv);
1561 io_subchannel_init_fields(sch); 1568 io_subchannel_init_fields(sch);
1562 rc = cio_commit_config(sch); 1569 rc = cio_commit_config(sch);
1563 if (rc) 1570 if (rc)
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index d024d2c21897..ba31ad88f4f7 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -5,68 +5,36 @@
5#include <asm/schid.h> 5#include <asm/schid.h>
6#include <asm/ccwdev.h> 6#include <asm/ccwdev.h>
7#include "css.h" 7#include "css.h"
8 8#include "orb.h"
9/*
10 * command-mode operation request block
11 */
12struct cmd_orb {
13 u32 intparm; /* interruption parameter */
14 u32 key : 4; /* flags, like key, suspend control, etc. */
15 u32 spnd : 1; /* suspend control */
16 u32 res1 : 1; /* reserved */
17 u32 mod : 1; /* modification control */
18 u32 sync : 1; /* synchronize control */
19 u32 fmt : 1; /* format control */
20 u32 pfch : 1; /* prefetch control */
21 u32 isic : 1; /* initial-status-interruption control */
22 u32 alcc : 1; /* address-limit-checking control */
23 u32 ssic : 1; /* suppress-suspended-interr. control */
24 u32 res2 : 1; /* reserved */
25 u32 c64 : 1; /* IDAW/QDIO 64 bit control */
26 u32 i2k : 1; /* IDAW 2/4kB block size control */
27 u32 lpm : 8; /* logical path mask */
28 u32 ils : 1; /* incorrect length */
29 u32 zero : 6; /* reserved zeros */
30 u32 orbx : 1; /* ORB extension control */
31 u32 cpa; /* channel program address */
32} __attribute__ ((packed, aligned(4)));
33
34/*
35 * transport-mode operation request block
36 */
37struct tm_orb {
38 u32 intparm;
39 u32 key:4;
40 u32 :9;
41 u32 b:1;
42 u32 :2;
43 u32 lpm:8;
44 u32 :7;
45 u32 x:1;
46 u32 tcw;
47 u32 prio:8;
48 u32 :8;
49 u32 rsvpgm:8;
50 u32 :8;
51 u32 :32;
52 u32 :32;
53 u32 :32;
54 u32 :32;
55} __attribute__ ((packed, aligned(4)));
56
57union orb {
58 struct cmd_orb cmd;
59 struct tm_orb tm;
60} __attribute__ ((packed, aligned(4)));
61 9
62struct io_subchannel_private { 10struct io_subchannel_private {
63 union orb orb; /* operation request block */ 11 union orb orb; /* operation request block */
64 struct ccw1 sense_ccw; /* static ccw for sense command */ 12 struct ccw1 sense_ccw; /* static ccw for sense command */
65} __attribute__ ((aligned(8))); 13 struct ccw_device *cdev;/* pointer to the child ccw device */
14 struct {
15 unsigned int suspend:1; /* allow suspend */
16 unsigned int prefetch:1;/* deny prefetch */
17 unsigned int inter:1; /* suppress intermediate interrupts */
18 } __packed options;
19} __aligned(8);
66 20
67#define to_io_private(n) ((struct io_subchannel_private *)n->private) 21#define to_io_private(n) ((struct io_subchannel_private *) \
68#define sch_get_cdev(n) (dev_get_drvdata(&n->dev)) 22 dev_get_drvdata(&(n)->dev))
69#define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c)) 23#define set_io_private(n, p) (dev_set_drvdata(&(n)->dev, p))
24
25static inline struct ccw_device *sch_get_cdev(struct subchannel *sch)
26{
27 struct io_subchannel_private *priv = to_io_private(sch);
28 return priv ? priv->cdev : NULL;
29}
30
31static inline void sch_set_cdev(struct subchannel *sch,
32 struct ccw_device *cdev)
33{
34 struct io_subchannel_private *priv = to_io_private(sch);
35 if (priv)
36 priv->cdev = cdev;
37}
70 38
71#define MAX_CIWS 8 39#define MAX_CIWS 8
72 40
@@ -191,23 +159,6 @@ struct ccw_device_private {
191 void *cmb_wait; /* deferred cmb enable/disable */ 159 void *cmb_wait; /* deferred cmb enable/disable */
192}; 160};
193 161
194static inline int ssch(struct subchannel_id schid, union orb *addr)
195{
196 register struct subchannel_id reg1 asm("1") = schid;
197 int ccode = -EIO;
198
199 asm volatile(
200 " ssch 0(%2)\n"
201 "0: ipm %0\n"
202 " srl %0,28\n"
203 "1:\n"
204 EX_TABLE(0b, 1b)
205 : "+d" (ccode)
206 : "d" (reg1), "a" (addr), "m" (*addr)
207 : "cc", "memory");
208 return ccode;
209}
210
211static inline int rsch(struct subchannel_id schid) 162static inline int rsch(struct subchannel_id schid)
212{ 163{
213 register struct subchannel_id reg1 asm("1") = schid; 164 register struct subchannel_id reg1 asm("1") = schid;
@@ -223,21 +174,6 @@ static inline int rsch(struct subchannel_id schid)
223 return ccode; 174 return ccode;
224} 175}
225 176
226static inline int csch(struct subchannel_id schid)
227{
228 register struct subchannel_id reg1 asm("1") = schid;
229 int ccode;
230
231 asm volatile(
232 " csch\n"
233 " ipm %0\n"
234 " srl %0,28"
235 : "=d" (ccode)
236 : "d" (reg1)
237 : "cc");
238 return ccode;
239}
240
241static inline int hsch(struct subchannel_id schid) 177static inline int hsch(struct subchannel_id schid)
242{ 178{
243 register struct subchannel_id reg1 asm("1") = schid; 179 register struct subchannel_id reg1 asm("1") = schid;
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h
index fac06155773f..4d80fc67a06b 100644
--- a/drivers/s390/cio/ioasm.h
+++ b/drivers/s390/cio/ioasm.h
@@ -3,6 +3,8 @@
3 3
4#include <asm/chpid.h> 4#include <asm/chpid.h>
5#include <asm/schid.h> 5#include <asm/schid.h>
6#include "orb.h"
7#include "cio.h"
6 8
7/* 9/*
8 * TPI info structure 10 * TPI info structure
@@ -87,6 +89,38 @@ static inline int tsch(struct subchannel_id schid, struct irb *addr)
87 return ccode; 89 return ccode;
88} 90}
89 91
92static inline int ssch(struct subchannel_id schid, union orb *addr)
93{
94 register struct subchannel_id reg1 asm("1") = schid;
95 int ccode = -EIO;
96
97 asm volatile(
98 " ssch 0(%2)\n"
99 "0: ipm %0\n"
100 " srl %0,28\n"
101 "1:\n"
102 EX_TABLE(0b, 1b)
103 : "+d" (ccode)
104 : "d" (reg1), "a" (addr), "m" (*addr)
105 : "cc", "memory");
106 return ccode;
107}
108
109static inline int csch(struct subchannel_id schid)
110{
111 register struct subchannel_id reg1 asm("1") = schid;
112 int ccode;
113
114 asm volatile(
115 " csch\n"
116 " ipm %0\n"
117 " srl %0,28"
118 : "=d" (ccode)
119 : "d" (reg1)
120 : "cc");
121 return ccode;
122}
123
90static inline int tpi(struct tpi_info *addr) 124static inline int tpi(struct tpi_info *addr)
91{ 125{
92 int ccode; 126 int ccode;
diff --git a/drivers/s390/cio/orb.h b/drivers/s390/cio/orb.h
new file mode 100644
index 000000000000..45a9865c2b36
--- /dev/null
+++ b/drivers/s390/cio/orb.h
@@ -0,0 +1,67 @@
1/*
2 * Orb related data structures.
3 *
4 * Copyright IBM Corp. 2007, 2011
5 *
6 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
7 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
8 * Sebastian Ott <sebott@linux.vnet.ibm.com>
9 */
10
11#ifndef S390_ORB_H
12#define S390_ORB_H
13
14/*
15 * Command-mode operation request block
16 */
17struct cmd_orb {
18 u32 intparm; /* interruption parameter */
19 u32 key:4; /* flags, like key, suspend control, etc. */
20 u32 spnd:1; /* suspend control */
21 u32 res1:1; /* reserved */
22 u32 mod:1; /* modification control */
23 u32 sync:1; /* synchronize control */
24 u32 fmt:1; /* format control */
25 u32 pfch:1; /* prefetch control */
26 u32 isic:1; /* initial-status-interruption control */
27 u32 alcc:1; /* address-limit-checking control */
28 u32 ssic:1; /* suppress-suspended-interr. control */
29 u32 res2:1; /* reserved */
30 u32 c64:1; /* IDAW/QDIO 64 bit control */
31 u32 i2k:1; /* IDAW 2/4kB block size control */
32 u32 lpm:8; /* logical path mask */
33 u32 ils:1; /* incorrect length */
34 u32 zero:6; /* reserved zeros */
35 u32 orbx:1; /* ORB extension control */
36 u32 cpa; /* channel program address */
37} __packed __aligned(4);
38
39/*
40 * Transport-mode operation request block
41 */
42struct tm_orb {
43 u32 intparm;
44 u32 key:4;
45 u32:9;
46 u32 b:1;
47 u32:2;
48 u32 lpm:8;
49 u32:7;
50 u32 x:1;
51 u32 tcw;
52 u32 prio:8;
53 u32:8;
54 u32 rsvpgm:8;
55 u32:8;
56 u32:32;
57 u32:32;
58 u32:32;
59 u32:32;
60} __packed __aligned(4);
61
62union orb {
63 struct cmd_orb cmd;
64 struct tm_orb tm;
65} __packed __aligned(4);
66
67#endif /* S390_ORB_H */