diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dcssblk.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/Makefile | 1 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/vmlogrdr.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/vmwatchdog.c | 338 | ||||
-rw-r--r-- | drivers/s390/cio/airq.c | 13 | ||||
-rw-r--r-- | drivers/s390/cio/ccwgroup.c | 28 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 71 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.c | 79 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.h | 2 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 16 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 4 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 2 |
14 files changed, 140 insertions, 422 deletions
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index ee0e85abe1fd..0f471750327e 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -593,7 +593,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char | |||
593 | dev_info->start = dcssblk_find_lowest_addr(dev_info); | 593 | dev_info->start = dcssblk_find_lowest_addr(dev_info); |
594 | dev_info->end = dcssblk_find_highest_addr(dev_info); | 594 | dev_info->end = dcssblk_find_highest_addr(dev_info); |
595 | 595 | ||
596 | dev_set_name(&dev_info->dev, dev_info->segment_name); | 596 | dev_set_name(&dev_info->dev, "%s", dev_info->segment_name); |
597 | dev_info->dev.release = dcssblk_release_segment; | 597 | dev_info->dev.release = dcssblk_release_segment; |
598 | dev_info->dev.groups = dcssblk_dev_attr_groups; | 598 | dev_info->dev.groups = dcssblk_dev_attr_groups; |
599 | INIT_LIST_HEAD(&dev_info->lh); | 599 | INIT_LIST_HEAD(&dev_info->lh); |
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 629fcc275e92..78b6ace7edcb 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile | |||
@@ -19,7 +19,6 @@ obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o | |||
19 | obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o | 19 | obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o |
20 | obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o | 20 | obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o |
21 | 21 | ||
22 | obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o | ||
23 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o | 22 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o |
24 | obj-$(CONFIG_VMCP) += vmcp.o | 23 | obj-$(CONFIG_VMCP) += vmcp.o |
25 | 24 | ||
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index cd9c91909596..b9a9f721716d 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -838,8 +838,6 @@ sclp_vt220_con_init(void) | |||
838 | { | 838 | { |
839 | int rc; | 839 | int rc; |
840 | 840 | ||
841 | if (!CONSOLE_IS_SCLP) | ||
842 | return 0; | ||
843 | rc = __sclp_vt220_init(sclp_console_pages); | 841 | rc = __sclp_vt220_init(sclp_console_pages); |
844 | if (rc) | 842 | if (rc) |
845 | return rc; | 843 | return rc; |
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index cf31d3321dab..a8848db7b09d 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -761,7 +761,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) | |||
761 | 761 | ||
762 | dev = kzalloc(sizeof(struct device), GFP_KERNEL); | 762 | dev = kzalloc(sizeof(struct device), GFP_KERNEL); |
763 | if (dev) { | 763 | if (dev) { |
764 | dev_set_name(dev, priv->internal_name); | 764 | dev_set_name(dev, "%s", priv->internal_name); |
765 | dev->bus = &iucv_bus; | 765 | dev->bus = &iucv_bus; |
766 | dev->parent = iucv_root; | 766 | dev->parent = iucv_root; |
767 | dev->driver = &vmlogrdr_driver; | 767 | dev->driver = &vmlogrdr_driver; |
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c deleted file mode 100644 index d5eac985976b..000000000000 --- a/drivers/s390/char/vmwatchdog.c +++ /dev/null | |||
@@ -1,338 +0,0 @@ | |||
1 | /* | ||
2 | * Watchdog implementation based on z/VM Watchdog Timer API | ||
3 | * | ||
4 | * Copyright IBM Corp. 2004, 2009 | ||
5 | * | ||
6 | * The user space watchdog daemon can use this driver as | ||
7 | * /dev/vmwatchdog to have z/VM execute the specified CP | ||
8 | * command when the timeout expires. The default command is | ||
9 | * "IPL", which which cause an immediate reboot. | ||
10 | */ | ||
11 | #define KMSG_COMPONENT "vmwatchdog" | ||
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/fs.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/miscdevice.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/moduleparam.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/suspend.h> | ||
22 | #include <linux/watchdog.h> | ||
23 | |||
24 | #include <asm/ebcdic.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/uaccess.h> | ||
27 | |||
28 | #define MAX_CMDLEN 240 | ||
29 | #define MIN_INTERVAL 15 | ||
30 | static char vmwdt_cmd[MAX_CMDLEN] = "IPL"; | ||
31 | static bool vmwdt_conceal; | ||
32 | |||
33 | static bool vmwdt_nowayout = WATCHDOG_NOWAYOUT; | ||
34 | |||
35 | MODULE_LICENSE("GPL"); | ||
36 | MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>"); | ||
37 | MODULE_DESCRIPTION("z/VM Watchdog Timer"); | ||
38 | module_param_string(cmd, vmwdt_cmd, MAX_CMDLEN, 0644); | ||
39 | MODULE_PARM_DESC(cmd, "CP command that is run when the watchdog triggers"); | ||
40 | module_param_named(conceal, vmwdt_conceal, bool, 0644); | ||
41 | MODULE_PARM_DESC(conceal, "Enable the CONCEAL CP option while the watchdog " | ||
42 | " is active"); | ||
43 | module_param_named(nowayout, vmwdt_nowayout, bool, 0); | ||
44 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started" | ||
45 | " (default=CONFIG_WATCHDOG_NOWAYOUT)"); | ||
46 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | ||
47 | |||
48 | static unsigned int vmwdt_interval = 60; | ||
49 | static unsigned long vmwdt_is_open; | ||
50 | static int vmwdt_expect_close; | ||
51 | |||
52 | static DEFINE_MUTEX(vmwdt_mutex); | ||
53 | |||
54 | #define VMWDT_OPEN 0 /* devnode is open or suspend in progress */ | ||
55 | #define VMWDT_RUNNING 1 /* The watchdog is armed */ | ||
56 | |||
57 | enum vmwdt_func { | ||
58 | /* function codes */ | ||
59 | wdt_init = 0, | ||
60 | wdt_change = 1, | ||
61 | wdt_cancel = 2, | ||
62 | /* flags */ | ||
63 | wdt_conceal = 0x80000000, | ||
64 | }; | ||
65 | |||
66 | static int __diag288(enum vmwdt_func func, unsigned int timeout, | ||
67 | char *cmd, size_t len) | ||
68 | { | ||
69 | register unsigned long __func asm("2") = func; | ||
70 | register unsigned long __timeout asm("3") = timeout; | ||
71 | register unsigned long __cmdp asm("4") = virt_to_phys(cmd); | ||
72 | register unsigned long __cmdl asm("5") = len; | ||
73 | int err; | ||
74 | |||
75 | err = -EINVAL; | ||
76 | asm volatile( | ||
77 | " diag %1,%3,0x288\n" | ||
78 | "0: la %0,0\n" | ||
79 | "1:\n" | ||
80 | EX_TABLE(0b,1b) | ||
81 | : "+d" (err) : "d"(__func), "d"(__timeout), | ||
82 | "d"(__cmdp), "d"(__cmdl) : "1", "cc"); | ||
83 | return err; | ||
84 | } | ||
85 | |||
86 | static int vmwdt_keepalive(void) | ||
87 | { | ||
88 | /* we allocate new memory every time to avoid having | ||
89 | * to track the state. static allocation is not an | ||
90 | * option since that might not be contiguous in real | ||
91 | * storage in case of a modular build */ | ||
92 | static char *ebc_cmd; | ||
93 | size_t len; | ||
94 | int ret; | ||
95 | unsigned int func; | ||
96 | |||
97 | ebc_cmd = kmalloc(MAX_CMDLEN, GFP_KERNEL); | ||
98 | if (!ebc_cmd) | ||
99 | return -ENOMEM; | ||
100 | |||
101 | len = strlcpy(ebc_cmd, vmwdt_cmd, MAX_CMDLEN); | ||
102 | ASCEBC(ebc_cmd, MAX_CMDLEN); | ||
103 | EBC_TOUPPER(ebc_cmd, MAX_CMDLEN); | ||
104 | |||
105 | func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init; | ||
106 | set_bit(VMWDT_RUNNING, &vmwdt_is_open); | ||
107 | ret = __diag288(func, vmwdt_interval, ebc_cmd, len); | ||
108 | WARN_ON(ret != 0); | ||
109 | kfree(ebc_cmd); | ||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | static int vmwdt_disable(void) | ||
114 | { | ||
115 | char cmd[] = {'\0'}; | ||
116 | int ret = __diag288(wdt_cancel, 0, cmd, 0); | ||
117 | WARN_ON(ret != 0); | ||
118 | clear_bit(VMWDT_RUNNING, &vmwdt_is_open); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | static int __init vmwdt_probe(void) | ||
123 | { | ||
124 | /* there is no real way to see if the watchdog is supported, | ||
125 | * so we try initializing it with a NOP command ("BEGIN") | ||
126 | * that won't cause any harm even if the following disable | ||
127 | * fails for some reason */ | ||
128 | char ebc_begin[] = { | ||
129 | 194, 197, 199, 201, 213 | ||
130 | }; | ||
131 | if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0) | ||
132 | return -EINVAL; | ||
133 | return vmwdt_disable(); | ||
134 | } | ||
135 | |||
136 | static int vmwdt_open(struct inode *i, struct file *f) | ||
137 | { | ||
138 | int ret; | ||
139 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) | ||
140 | return -EBUSY; | ||
141 | ret = vmwdt_keepalive(); | ||
142 | if (ret) | ||
143 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); | ||
144 | return ret ? ret : nonseekable_open(i, f); | ||
145 | } | ||
146 | |||
147 | static int vmwdt_close(struct inode *i, struct file *f) | ||
148 | { | ||
149 | if (vmwdt_expect_close == 42) | ||
150 | vmwdt_disable(); | ||
151 | vmwdt_expect_close = 0; | ||
152 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static struct watchdog_info vmwdt_info = { | ||
157 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | ||
158 | .firmware_version = 0, | ||
159 | .identity = "z/VM Watchdog Timer", | ||
160 | }; | ||
161 | |||
162 | static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg) | ||
163 | { | ||
164 | switch (cmd) { | ||
165 | case WDIOC_GETSUPPORT: | ||
166 | if (copy_to_user((void __user *)arg, &vmwdt_info, | ||
167 | sizeof(vmwdt_info))) | ||
168 | return -EFAULT; | ||
169 | return 0; | ||
170 | case WDIOC_GETSTATUS: | ||
171 | case WDIOC_GETBOOTSTATUS: | ||
172 | return put_user(0, (int __user *)arg); | ||
173 | case WDIOC_GETTEMP: | ||
174 | return -EINVAL; | ||
175 | case WDIOC_SETOPTIONS: | ||
176 | { | ||
177 | int options, ret; | ||
178 | if (get_user(options, (int __user *)arg)) | ||
179 | return -EFAULT; | ||
180 | ret = -EINVAL; | ||
181 | if (options & WDIOS_DISABLECARD) { | ||
182 | ret = vmwdt_disable(); | ||
183 | if (ret) | ||
184 | return ret; | ||
185 | } | ||
186 | if (options & WDIOS_ENABLECARD) { | ||
187 | ret = vmwdt_keepalive(); | ||
188 | } | ||
189 | return ret; | ||
190 | } | ||
191 | case WDIOC_GETTIMEOUT: | ||
192 | return put_user(vmwdt_interval, (int __user *)arg); | ||
193 | case WDIOC_SETTIMEOUT: | ||
194 | { | ||
195 | int interval; | ||
196 | if (get_user(interval, (int __user *)arg)) | ||
197 | return -EFAULT; | ||
198 | if (interval < MIN_INTERVAL) | ||
199 | return -EINVAL; | ||
200 | vmwdt_interval = interval; | ||
201 | } | ||
202 | return vmwdt_keepalive(); | ||
203 | case WDIOC_KEEPALIVE: | ||
204 | return vmwdt_keepalive(); | ||
205 | } | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | |||
209 | static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | ||
210 | { | ||
211 | int rc; | ||
212 | |||
213 | mutex_lock(&vmwdt_mutex); | ||
214 | rc = __vmwdt_ioctl(cmd, arg); | ||
215 | mutex_unlock(&vmwdt_mutex); | ||
216 | return (long) rc; | ||
217 | } | ||
218 | |||
219 | static ssize_t vmwdt_write(struct file *f, const char __user *buf, | ||
220 | size_t count, loff_t *ppos) | ||
221 | { | ||
222 | if(count) { | ||
223 | if (!vmwdt_nowayout) { | ||
224 | size_t i; | ||
225 | |||
226 | /* note: just in case someone wrote the magic character | ||
227 | * five months ago... */ | ||
228 | vmwdt_expect_close = 0; | ||
229 | |||
230 | for (i = 0; i != count; i++) { | ||
231 | char c; | ||
232 | if (get_user(c, buf+i)) | ||
233 | return -EFAULT; | ||
234 | if (c == 'V') | ||
235 | vmwdt_expect_close = 42; | ||
236 | } | ||
237 | } | ||
238 | /* someone wrote to us, we should restart timer */ | ||
239 | vmwdt_keepalive(); | ||
240 | } | ||
241 | return count; | ||
242 | } | ||
243 | |||
244 | static int vmwdt_resume(void) | ||
245 | { | ||
246 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); | ||
247 | return NOTIFY_DONE; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * It makes no sense to go into suspend while the watchdog is running. | ||
252 | * Depending on the memory size, the watchdog might trigger, while we | ||
253 | * are still saving the memory. | ||
254 | * We reuse the open flag to ensure that suspend and watchdog open are | ||
255 | * exclusive operations | ||
256 | */ | ||
257 | static int vmwdt_suspend(void) | ||
258 | { | ||
259 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { | ||
260 | pr_err("The system cannot be suspended while the watchdog" | ||
261 | " is in use\n"); | ||
262 | return notifier_from_errno(-EBUSY); | ||
263 | } | ||
264 | if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) { | ||
265 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); | ||
266 | pr_err("The system cannot be suspended while the watchdog" | ||
267 | " is running\n"); | ||
268 | return notifier_from_errno(-EBUSY); | ||
269 | } | ||
270 | return NOTIFY_DONE; | ||
271 | } | ||
272 | |||
273 | /* | ||
274 | * This function is called for suspend and resume. | ||
275 | */ | ||
276 | static int vmwdt_power_event(struct notifier_block *this, unsigned long event, | ||
277 | void *ptr) | ||
278 | { | ||
279 | switch (event) { | ||
280 | case PM_POST_HIBERNATION: | ||
281 | case PM_POST_SUSPEND: | ||
282 | return vmwdt_resume(); | ||
283 | case PM_HIBERNATION_PREPARE: | ||
284 | case PM_SUSPEND_PREPARE: | ||
285 | return vmwdt_suspend(); | ||
286 | default: | ||
287 | return NOTIFY_DONE; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | static struct notifier_block vmwdt_power_notifier = { | ||
292 | .notifier_call = vmwdt_power_event, | ||
293 | }; | ||
294 | |||
295 | static const struct file_operations vmwdt_fops = { | ||
296 | .open = &vmwdt_open, | ||
297 | .release = &vmwdt_close, | ||
298 | .unlocked_ioctl = &vmwdt_ioctl, | ||
299 | .write = &vmwdt_write, | ||
300 | .owner = THIS_MODULE, | ||
301 | .llseek = noop_llseek, | ||
302 | }; | ||
303 | |||
304 | static struct miscdevice vmwdt_dev = { | ||
305 | .minor = WATCHDOG_MINOR, | ||
306 | .name = "watchdog", | ||
307 | .fops = &vmwdt_fops, | ||
308 | }; | ||
309 | |||
310 | static int __init vmwdt_init(void) | ||
311 | { | ||
312 | int ret; | ||
313 | |||
314 | ret = vmwdt_probe(); | ||
315 | if (ret) | ||
316 | return ret; | ||
317 | ret = register_pm_notifier(&vmwdt_power_notifier); | ||
318 | if (ret) | ||
319 | return ret; | ||
320 | /* | ||
321 | * misc_register() has to be the last action in module_init(), because | ||
322 | * file operations will be available right after this. | ||
323 | */ | ||
324 | ret = misc_register(&vmwdt_dev); | ||
325 | if (ret) { | ||
326 | unregister_pm_notifier(&vmwdt_power_notifier); | ||
327 | return ret; | ||
328 | } | ||
329 | return 0; | ||
330 | } | ||
331 | module_init(vmwdt_init); | ||
332 | |||
333 | static void __exit vmwdt_exit(void) | ||
334 | { | ||
335 | unregister_pm_notifier(&vmwdt_power_notifier); | ||
336 | misc_deregister(&vmwdt_dev); | ||
337 | } | ||
338 | module_exit(vmwdt_exit); | ||
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index 445564c790f6..00bfbee0af9e 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c | |||
@@ -196,11 +196,11 @@ EXPORT_SYMBOL(airq_iv_release); | |||
196 | */ | 196 | */ |
197 | unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num) | 197 | unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num) |
198 | { | 198 | { |
199 | unsigned long bit, i; | 199 | unsigned long bit, i, flags; |
200 | 200 | ||
201 | if (!iv->avail || num == 0) | 201 | if (!iv->avail || num == 0) |
202 | return -1UL; | 202 | return -1UL; |
203 | spin_lock(&iv->lock); | 203 | spin_lock_irqsave(&iv->lock, flags); |
204 | bit = find_first_bit_inv(iv->avail, iv->bits); | 204 | bit = find_first_bit_inv(iv->avail, iv->bits); |
205 | while (bit + num <= iv->bits) { | 205 | while (bit + num <= iv->bits) { |
206 | for (i = 1; i < num; i++) | 206 | for (i = 1; i < num; i++) |
@@ -218,9 +218,8 @@ unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num) | |||
218 | } | 218 | } |
219 | if (bit + num > iv->bits) | 219 | if (bit + num > iv->bits) |
220 | bit = -1UL; | 220 | bit = -1UL; |
221 | spin_unlock(&iv->lock); | 221 | spin_unlock_irqrestore(&iv->lock, flags); |
222 | return bit; | 222 | return bit; |
223 | |||
224 | } | 223 | } |
225 | EXPORT_SYMBOL(airq_iv_alloc); | 224 | EXPORT_SYMBOL(airq_iv_alloc); |
226 | 225 | ||
@@ -232,11 +231,11 @@ EXPORT_SYMBOL(airq_iv_alloc); | |||
232 | */ | 231 | */ |
233 | void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num) | 232 | void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num) |
234 | { | 233 | { |
235 | unsigned long i; | 234 | unsigned long i, flags; |
236 | 235 | ||
237 | if (!iv->avail || num == 0) | 236 | if (!iv->avail || num == 0) |
238 | return; | 237 | return; |
239 | spin_lock(&iv->lock); | 238 | spin_lock_irqsave(&iv->lock, flags); |
240 | for (i = 0; i < num; i++) { | 239 | for (i = 0; i < num; i++) { |
241 | /* Clear (possibly left over) interrupt bit */ | 240 | /* Clear (possibly left over) interrupt bit */ |
242 | clear_bit_inv(bit + i, iv->vector); | 241 | clear_bit_inv(bit + i, iv->vector); |
@@ -248,7 +247,7 @@ void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num) | |||
248 | while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail)) | 247 | while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail)) |
249 | iv->end--; | 248 | iv->end--; |
250 | } | 249 | } |
251 | spin_unlock(&iv->lock); | 250 | spin_unlock_irqrestore(&iv->lock, flags); |
252 | } | 251 | } |
253 | EXPORT_SYMBOL(airq_iv_free); | 252 | EXPORT_SYMBOL(airq_iv_free); |
254 | 253 | ||
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index dfd7bc681c25..e443b0d0b236 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -184,7 +184,7 @@ static ssize_t ccwgroup_ungroup_store(struct device *dev, | |||
184 | const char *buf, size_t count) | 184 | const char *buf, size_t count) |
185 | { | 185 | { |
186 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | 186 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
187 | int rc; | 187 | int rc = 0; |
188 | 188 | ||
189 | /* Prevent concurrent online/offline processing and ungrouping. */ | 189 | /* Prevent concurrent online/offline processing and ungrouping. */ |
190 | if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) | 190 | if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) |
@@ -196,11 +196,12 @@ static ssize_t ccwgroup_ungroup_store(struct device *dev, | |||
196 | 196 | ||
197 | if (device_remove_file_self(dev, attr)) | 197 | if (device_remove_file_self(dev, attr)) |
198 | ccwgroup_ungroup(gdev); | 198 | ccwgroup_ungroup(gdev); |
199 | else | ||
200 | rc = -ENODEV; | ||
199 | out: | 201 | out: |
200 | if (rc) { | 202 | if (rc) { |
201 | if (rc != -EAGAIN) | 203 | /* Release onoff "lock" when ungrouping failed. */ |
202 | /* Release onoff "lock" when ungrouping failed. */ | 204 | atomic_set(&gdev->onoff, 0); |
203 | atomic_set(&gdev->onoff, 0); | ||
204 | return rc; | 205 | return rc; |
205 | } | 206 | } |
206 | return count; | 207 | return count; |
@@ -227,6 +228,7 @@ static void ccwgroup_ungroup_workfn(struct work_struct *work) | |||
227 | container_of(work, struct ccwgroup_device, ungroup_work); | 228 | container_of(work, struct ccwgroup_device, ungroup_work); |
228 | 229 | ||
229 | ccwgroup_ungroup(gdev); | 230 | ccwgroup_ungroup(gdev); |
231 | put_device(&gdev->dev); | ||
230 | } | 232 | } |
231 | 233 | ||
232 | static void ccwgroup_release(struct device *dev) | 234 | static void ccwgroup_release(struct device *dev) |
@@ -412,8 +414,10 @@ static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, | |||
412 | { | 414 | { |
413 | struct ccwgroup_device *gdev = to_ccwgroupdev(data); | 415 | struct ccwgroup_device *gdev = to_ccwgroupdev(data); |
414 | 416 | ||
415 | if (action == BUS_NOTIFY_UNBIND_DRIVER) | 417 | if (action == BUS_NOTIFY_UNBIND_DRIVER) { |
418 | get_device(&gdev->dev); | ||
416 | schedule_work(&gdev->ungroup_work); | 419 | schedule_work(&gdev->ungroup_work); |
420 | } | ||
417 | 421 | ||
418 | return NOTIFY_OK; | 422 | return NOTIFY_OK; |
419 | } | 423 | } |
@@ -582,11 +586,7 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) | |||
582 | __ccwgroup_match_all))) { | 586 | __ccwgroup_match_all))) { |
583 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | 587 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); |
584 | 588 | ||
585 | mutex_lock(&gdev->reg_mutex); | 589 | ccwgroup_ungroup(gdev); |
586 | __ccwgroup_remove_symlinks(gdev); | ||
587 | device_unregister(dev); | ||
588 | __ccwgroup_remove_cdev_refs(gdev); | ||
589 | mutex_unlock(&gdev->reg_mutex); | ||
590 | put_device(dev); | 590 | put_device(dev); |
591 | } | 591 | } |
592 | driver_unregister(&cdriver->driver); | 592 | driver_unregister(&cdriver->driver); |
@@ -633,13 +633,7 @@ void ccwgroup_remove_ccwdev(struct ccw_device *cdev) | |||
633 | get_device(&gdev->dev); | 633 | get_device(&gdev->dev); |
634 | spin_unlock_irq(cdev->ccwlock); | 634 | spin_unlock_irq(cdev->ccwlock); |
635 | /* Unregister group device. */ | 635 | /* Unregister group device. */ |
636 | mutex_lock(&gdev->reg_mutex); | 636 | ccwgroup_ungroup(gdev); |
637 | if (device_is_registered(&gdev->dev)) { | ||
638 | __ccwgroup_remove_symlinks(gdev); | ||
639 | device_unregister(&gdev->dev); | ||
640 | __ccwgroup_remove_cdev_refs(gdev); | ||
641 | } | ||
642 | mutex_unlock(&gdev->reg_mutex); | ||
643 | /* Release ccwgroup device reference for local processing. */ | 637 | /* Release ccwgroup device reference for local processing. */ |
644 | put_device(&gdev->dev); | 638 | put_device(&gdev->dev); |
645 | } | 639 | } |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 77f9c92df4b9..2905d8b0ec95 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -602,6 +602,7 @@ void __init init_cio_interrupts(void) | |||
602 | 602 | ||
603 | #ifdef CONFIG_CCW_CONSOLE | 603 | #ifdef CONFIG_CCW_CONSOLE |
604 | static struct subchannel *console_sch; | 604 | static struct subchannel *console_sch; |
605 | static struct lock_class_key console_sch_key; | ||
605 | 606 | ||
606 | /* | 607 | /* |
607 | * Use cio_tsch to update the subchannel status and call the interrupt handler | 608 | * Use cio_tsch to update the subchannel status and call the interrupt handler |
@@ -686,6 +687,7 @@ struct subchannel *cio_probe_console(void) | |||
686 | if (IS_ERR(sch)) | 687 | if (IS_ERR(sch)) |
687 | return sch; | 688 | return sch; |
688 | 689 | ||
690 | lockdep_set_class(sch->lock, &console_sch_key); | ||
689 | isc_register(CONSOLE_ISC); | 691 | isc_register(CONSOLE_ISC); |
690 | sch->config.isc = CONSOLE_ISC; | 692 | sch->config.isc = CONSOLE_ISC; |
691 | sch->config.intparm = (u32)(addr_t)sch; | 693 | sch->config.intparm = (u32)(addr_t)sch; |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index d8d9b5b5cc56..dfef5e63cb7b 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -678,18 +678,11 @@ static const struct attribute_group *ccwdev_attr_groups[] = { | |||
678 | NULL, | 678 | NULL, |
679 | }; | 679 | }; |
680 | 680 | ||
681 | /* this is a simple abstraction for device_register that sets the | 681 | static int ccw_device_add(struct ccw_device *cdev) |
682 | * correct bus type and adds the bus specific files */ | ||
683 | static int ccw_device_register(struct ccw_device *cdev) | ||
684 | { | 682 | { |
685 | struct device *dev = &cdev->dev; | 683 | struct device *dev = &cdev->dev; |
686 | int ret; | ||
687 | 684 | ||
688 | dev->bus = &ccw_bus_type; | 685 | dev->bus = &ccw_bus_type; |
689 | ret = dev_set_name(&cdev->dev, "0.%x.%04x", cdev->private->dev_id.ssid, | ||
690 | cdev->private->dev_id.devno); | ||
691 | if (ret) | ||
692 | return ret; | ||
693 | return device_add(dev); | 686 | return device_add(dev); |
694 | } | 687 | } |
695 | 688 | ||
@@ -764,22 +757,46 @@ static void ccw_device_todo(struct work_struct *work); | |||
764 | static int io_subchannel_initialize_dev(struct subchannel *sch, | 757 | static int io_subchannel_initialize_dev(struct subchannel *sch, |
765 | struct ccw_device *cdev) | 758 | struct ccw_device *cdev) |
766 | { | 759 | { |
767 | cdev->private->cdev = cdev; | 760 | struct ccw_device_private *priv = cdev->private; |
768 | cdev->private->int_class = IRQIO_CIO; | 761 | int ret; |
769 | atomic_set(&cdev->private->onoff, 0); | 762 | |
763 | priv->cdev = cdev; | ||
764 | priv->int_class = IRQIO_CIO; | ||
765 | priv->state = DEV_STATE_NOT_OPER; | ||
766 | priv->dev_id.devno = sch->schib.pmcw.dev; | ||
767 | priv->dev_id.ssid = sch->schid.ssid; | ||
768 | priv->schid = sch->schid; | ||
769 | |||
770 | INIT_WORK(&priv->todo_work, ccw_device_todo); | ||
771 | INIT_LIST_HEAD(&priv->cmb_list); | ||
772 | init_waitqueue_head(&priv->wait_q); | ||
773 | init_timer(&priv->timer); | ||
774 | |||
775 | atomic_set(&priv->onoff, 0); | ||
776 | cdev->ccwlock = sch->lock; | ||
770 | cdev->dev.parent = &sch->dev; | 777 | cdev->dev.parent = &sch->dev; |
771 | cdev->dev.release = ccw_device_release; | 778 | cdev->dev.release = ccw_device_release; |
772 | INIT_WORK(&cdev->private->todo_work, ccw_device_todo); | ||
773 | cdev->dev.groups = ccwdev_attr_groups; | 779 | cdev->dev.groups = ccwdev_attr_groups; |
774 | /* Do first half of device_register. */ | 780 | /* Do first half of device_register. */ |
775 | device_initialize(&cdev->dev); | 781 | device_initialize(&cdev->dev); |
782 | ret = dev_set_name(&cdev->dev, "0.%x.%04x", cdev->private->dev_id.ssid, | ||
783 | cdev->private->dev_id.devno); | ||
784 | if (ret) | ||
785 | goto out_put; | ||
776 | if (!get_device(&sch->dev)) { | 786 | if (!get_device(&sch->dev)) { |
777 | /* Release reference from device_initialize(). */ | 787 | ret = -ENODEV; |
778 | put_device(&cdev->dev); | 788 | goto out_put; |
779 | return -ENODEV; | ||
780 | } | 789 | } |
781 | cdev->private->flags.initialized = 1; | 790 | priv->flags.initialized = 1; |
791 | spin_lock_irq(sch->lock); | ||
792 | sch_set_cdev(sch, cdev); | ||
793 | spin_unlock_irq(sch->lock); | ||
782 | return 0; | 794 | return 0; |
795 | |||
796 | out_put: | ||
797 | /* Release reference from device_initialize(). */ | ||
798 | put_device(&cdev->dev); | ||
799 | return ret; | ||
783 | } | 800 | } |
784 | 801 | ||
785 | static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) | 802 | static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) |
@@ -858,7 +875,7 @@ static void io_subchannel_register(struct ccw_device *cdev) | |||
858 | dev_set_uevent_suppress(&sch->dev, 0); | 875 | dev_set_uevent_suppress(&sch->dev, 0); |
859 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 876 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
860 | /* make it known to the system */ | 877 | /* make it known to the system */ |
861 | ret = ccw_device_register(cdev); | 878 | ret = ccw_device_add(cdev); |
862 | if (ret) { | 879 | if (ret) { |
863 | CIO_MSG_EVENT(0, "Could not register ccw dev 0.%x.%04x: %d\n", | 880 | CIO_MSG_EVENT(0, "Could not register ccw dev 0.%x.%04x: %d\n", |
864 | cdev->private->dev_id.ssid, | 881 | cdev->private->dev_id.ssid, |
@@ -923,26 +940,11 @@ io_subchannel_recog_done(struct ccw_device *cdev) | |||
923 | 940 | ||
924 | static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) | 941 | static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) |
925 | { | 942 | { |
926 | struct ccw_device_private *priv; | ||
927 | |||
928 | cdev->ccwlock = sch->lock; | ||
929 | |||
930 | /* Init private data. */ | ||
931 | priv = cdev->private; | ||
932 | priv->dev_id.devno = sch->schib.pmcw.dev; | ||
933 | priv->dev_id.ssid = sch->schid.ssid; | ||
934 | priv->schid = sch->schid; | ||
935 | priv->state = DEV_STATE_NOT_OPER; | ||
936 | INIT_LIST_HEAD(&priv->cmb_list); | ||
937 | init_waitqueue_head(&priv->wait_q); | ||
938 | init_timer(&priv->timer); | ||
939 | |||
940 | /* Increase counter of devices currently in recognition. */ | 943 | /* Increase counter of devices currently in recognition. */ |
941 | atomic_inc(&ccw_device_init_count); | 944 | atomic_inc(&ccw_device_init_count); |
942 | 945 | ||
943 | /* Start async. device sensing. */ | 946 | /* Start async. device sensing. */ |
944 | spin_lock_irq(sch->lock); | 947 | spin_lock_irq(sch->lock); |
945 | sch_set_cdev(sch, cdev); | ||
946 | ccw_device_recognition(cdev); | 948 | ccw_device_recognition(cdev); |
947 | spin_unlock_irq(sch->lock); | 949 | spin_unlock_irq(sch->lock); |
948 | } | 950 | } |
@@ -1083,7 +1085,7 @@ static int io_subchannel_probe(struct subchannel *sch) | |||
1083 | dev_set_uevent_suppress(&sch->dev, 0); | 1085 | dev_set_uevent_suppress(&sch->dev, 0); |
1084 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 1086 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
1085 | cdev = sch_get_cdev(sch); | 1087 | cdev = sch_get_cdev(sch); |
1086 | rc = ccw_device_register(cdev); | 1088 | rc = ccw_device_add(cdev); |
1087 | if (rc) { | 1089 | if (rc) { |
1088 | /* Release online reference. */ | 1090 | /* Release online reference. */ |
1089 | put_device(&cdev->dev); | 1091 | put_device(&cdev->dev); |
@@ -1597,7 +1599,6 @@ int __init ccw_device_enable_console(struct ccw_device *cdev) | |||
1597 | if (rc) | 1599 | if (rc) |
1598 | return rc; | 1600 | return rc; |
1599 | sch->driver = &io_subchannel_driver; | 1601 | sch->driver = &io_subchannel_driver; |
1600 | sch_set_cdev(sch, cdev); | ||
1601 | io_subchannel_recog(cdev, sch); | 1602 | io_subchannel_recog(cdev, sch); |
1602 | /* Now wait for the async. recognition to come to an end. */ | 1603 | /* Now wait for the async. recognition to come to an end. */ |
1603 | spin_lock_irq(cdev->ccwlock); | 1604 | spin_lock_irq(cdev->ccwlock); |
@@ -1639,6 +1640,7 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv) | |||
1639 | put_device(&sch->dev); | 1640 | put_device(&sch->dev); |
1640 | return ERR_PTR(-ENOMEM); | 1641 | return ERR_PTR(-ENOMEM); |
1641 | } | 1642 | } |
1643 | set_io_private(sch, io_priv); | ||
1642 | cdev = io_subchannel_create_ccwdev(sch); | 1644 | cdev = io_subchannel_create_ccwdev(sch); |
1643 | if (IS_ERR(cdev)) { | 1645 | if (IS_ERR(cdev)) { |
1644 | put_device(&sch->dev); | 1646 | put_device(&sch->dev); |
@@ -1646,7 +1648,6 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv) | |||
1646 | return cdev; | 1648 | return cdev; |
1647 | } | 1649 | } |
1648 | cdev->drv = drv; | 1650 | cdev->drv = drv; |
1649 | set_io_private(sch, io_priv); | ||
1650 | ccw_device_set_int_class(cdev); | 1651 | ccw_device_set_int_class(cdev); |
1651 | return cdev; | 1652 | return cdev; |
1652 | } | 1653 | } |
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index 4221b02085ad..f1f3baa8e6e4 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/debugfs.h> | 7 | #include <linux/debugfs.h> |
8 | #include <linux/uaccess.h> | 8 | #include <linux/uaccess.h> |
9 | #include <linux/export.h> | 9 | #include <linux/export.h> |
10 | #include <linux/slab.h> | ||
10 | #include <asm/debug.h> | 11 | #include <asm/debug.h> |
11 | #include "qdio_debug.h" | 12 | #include "qdio_debug.h" |
12 | #include "qdio.h" | 13 | #include "qdio.h" |
@@ -16,11 +17,51 @@ debug_info_t *qdio_dbf_error; | |||
16 | 17 | ||
17 | static struct dentry *debugfs_root; | 18 | static struct dentry *debugfs_root; |
18 | #define QDIO_DEBUGFS_NAME_LEN 10 | 19 | #define QDIO_DEBUGFS_NAME_LEN 10 |
20 | #define QDIO_DBF_NAME_LEN 20 | ||
19 | 21 | ||
20 | void qdio_allocate_dbf(struct qdio_initialize *init_data, | 22 | struct qdio_dbf_entry { |
23 | char dbf_name[QDIO_DBF_NAME_LEN]; | ||
24 | debug_info_t *dbf_info; | ||
25 | struct list_head dbf_list; | ||
26 | }; | ||
27 | |||
28 | static LIST_HEAD(qdio_dbf_list); | ||
29 | static DEFINE_MUTEX(qdio_dbf_list_mutex); | ||
30 | |||
31 | static debug_info_t *qdio_get_dbf_entry(char *name) | ||
32 | { | ||
33 | struct qdio_dbf_entry *entry; | ||
34 | debug_info_t *rc = NULL; | ||
35 | |||
36 | mutex_lock(&qdio_dbf_list_mutex); | ||
37 | list_for_each_entry(entry, &qdio_dbf_list, dbf_list) { | ||
38 | if (strcmp(entry->dbf_name, name) == 0) { | ||
39 | rc = entry->dbf_info; | ||
40 | break; | ||
41 | } | ||
42 | } | ||
43 | mutex_unlock(&qdio_dbf_list_mutex); | ||
44 | return rc; | ||
45 | } | ||
46 | |||
47 | static void qdio_clear_dbf_list(void) | ||
48 | { | ||
49 | struct qdio_dbf_entry *entry, *tmp; | ||
50 | |||
51 | mutex_lock(&qdio_dbf_list_mutex); | ||
52 | list_for_each_entry_safe(entry, tmp, &qdio_dbf_list, dbf_list) { | ||
53 | list_del(&entry->dbf_list); | ||
54 | debug_unregister(entry->dbf_info); | ||
55 | kfree(entry); | ||
56 | } | ||
57 | mutex_unlock(&qdio_dbf_list_mutex); | ||
58 | } | ||
59 | |||
60 | int qdio_allocate_dbf(struct qdio_initialize *init_data, | ||
21 | struct qdio_irq *irq_ptr) | 61 | struct qdio_irq *irq_ptr) |
22 | { | 62 | { |
23 | char text[20]; | 63 | char text[QDIO_DBF_NAME_LEN]; |
64 | struct qdio_dbf_entry *new_entry; | ||
24 | 65 | ||
25 | DBF_EVENT("qfmt:%1d", init_data->q_format); | 66 | DBF_EVENT("qfmt:%1d", init_data->q_format); |
26 | DBF_HEX(init_data->adapter_name, 8); | 67 | DBF_HEX(init_data->adapter_name, 8); |
@@ -38,11 +79,34 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data, | |||
38 | DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); | 79 | DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); |
39 | 80 | ||
40 | /* allocate trace view for the interface */ | 81 | /* allocate trace view for the interface */ |
41 | snprintf(text, 20, "qdio_%s", dev_name(&init_data->cdev->dev)); | 82 | snprintf(text, QDIO_DBF_NAME_LEN, "qdio_%s", |
42 | irq_ptr->debug_area = debug_register(text, 2, 1, 16); | 83 | dev_name(&init_data->cdev->dev)); |
43 | debug_register_view(irq_ptr->debug_area, &debug_hex_ascii_view); | 84 | irq_ptr->debug_area = qdio_get_dbf_entry(text); |
44 | debug_set_level(irq_ptr->debug_area, DBF_WARN); | 85 | if (irq_ptr->debug_area) |
45 | DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created"); | 86 | DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf reused"); |
87 | else { | ||
88 | irq_ptr->debug_area = debug_register(text, 2, 1, 16); | ||
89 | if (!irq_ptr->debug_area) | ||
90 | return -ENOMEM; | ||
91 | if (debug_register_view(irq_ptr->debug_area, | ||
92 | &debug_hex_ascii_view)) { | ||
93 | debug_unregister(irq_ptr->debug_area); | ||
94 | return -ENOMEM; | ||
95 | } | ||
96 | debug_set_level(irq_ptr->debug_area, DBF_WARN); | ||
97 | DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created"); | ||
98 | new_entry = kzalloc(sizeof(struct qdio_dbf_entry), GFP_KERNEL); | ||
99 | if (!new_entry) { | ||
100 | debug_unregister(irq_ptr->debug_area); | ||
101 | return -ENOMEM; | ||
102 | } | ||
103 | strlcpy(new_entry->dbf_name, text, QDIO_DBF_NAME_LEN); | ||
104 | new_entry->dbf_info = irq_ptr->debug_area; | ||
105 | mutex_lock(&qdio_dbf_list_mutex); | ||
106 | list_add(&new_entry->dbf_list, &qdio_dbf_list); | ||
107 | mutex_unlock(&qdio_dbf_list_mutex); | ||
108 | } | ||
109 | return 0; | ||
46 | } | 110 | } |
47 | 111 | ||
48 | static int qstat_show(struct seq_file *m, void *v) | 112 | static int qstat_show(struct seq_file *m, void *v) |
@@ -300,6 +364,7 @@ int __init qdio_debug_init(void) | |||
300 | 364 | ||
301 | void qdio_debug_exit(void) | 365 | void qdio_debug_exit(void) |
302 | { | 366 | { |
367 | qdio_clear_dbf_list(); | ||
303 | debugfs_remove(debugfs_root); | 368 | debugfs_remove(debugfs_root); |
304 | if (qdio_dbf_setup) | 369 | if (qdio_dbf_setup) |
305 | debug_unregister(qdio_dbf_setup); | 370 | debug_unregister(qdio_dbf_setup); |
diff --git a/drivers/s390/cio/qdio_debug.h b/drivers/s390/cio/qdio_debug.h index dfac9bfefea3..f33ce8577619 100644 --- a/drivers/s390/cio/qdio_debug.h +++ b/drivers/s390/cio/qdio_debug.h | |||
@@ -75,7 +75,7 @@ static inline void DBF_DEV_HEX(struct qdio_irq *dev, void *addr, | |||
75 | } | 75 | } |
76 | } | 76 | } |
77 | 77 | ||
78 | void qdio_allocate_dbf(struct qdio_initialize *init_data, | 78 | int qdio_allocate_dbf(struct qdio_initialize *init_data, |
79 | struct qdio_irq *irq_ptr); | 79 | struct qdio_irq *irq_ptr); |
80 | void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, | 80 | void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, |
81 | struct ccw_device *cdev); | 81 | struct ccw_device *cdev); |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 77466c4faabb..848e3b64ea6e 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -409,17 +409,16 @@ static inline void qdio_stop_polling(struct qdio_q *q) | |||
409 | set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT); | 409 | set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT); |
410 | } | 410 | } |
411 | 411 | ||
412 | static inline void account_sbals(struct qdio_q *q, int count) | 412 | static inline void account_sbals(struct qdio_q *q, unsigned int count) |
413 | { | 413 | { |
414 | int pos = 0; | 414 | int pos; |
415 | 415 | ||
416 | q->q_stats.nr_sbal_total += count; | 416 | q->q_stats.nr_sbal_total += count; |
417 | if (count == QDIO_MAX_BUFFERS_MASK) { | 417 | if (count == QDIO_MAX_BUFFERS_MASK) { |
418 | q->q_stats.nr_sbals[7]++; | 418 | q->q_stats.nr_sbals[7]++; |
419 | return; | 419 | return; |
420 | } | 420 | } |
421 | while (count >>= 1) | 421 | pos = ilog2(count); |
422 | pos++; | ||
423 | q->q_stats.nr_sbals[pos]++; | 422 | q->q_stats.nr_sbals[pos]++; |
424 | } | 423 | } |
425 | 424 | ||
@@ -1234,12 +1233,10 @@ int qdio_free(struct ccw_device *cdev) | |||
1234 | return -ENODEV; | 1233 | return -ENODEV; |
1235 | 1234 | ||
1236 | DBF_EVENT("qfree:%4x", cdev->private->schid.sch_no); | 1235 | DBF_EVENT("qfree:%4x", cdev->private->schid.sch_no); |
1236 | DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf abandoned"); | ||
1237 | mutex_lock(&irq_ptr->setup_mutex); | 1237 | mutex_lock(&irq_ptr->setup_mutex); |
1238 | 1238 | ||
1239 | if (irq_ptr->debug_area != NULL) { | 1239 | irq_ptr->debug_area = NULL; |
1240 | debug_unregister(irq_ptr->debug_area); | ||
1241 | irq_ptr->debug_area = NULL; | ||
1242 | } | ||
1243 | cdev->private->qdio_data = NULL; | 1240 | cdev->private->qdio_data = NULL; |
1244 | mutex_unlock(&irq_ptr->setup_mutex); | 1241 | mutex_unlock(&irq_ptr->setup_mutex); |
1245 | 1242 | ||
@@ -1276,7 +1273,8 @@ int qdio_allocate(struct qdio_initialize *init_data) | |||
1276 | goto out_err; | 1273 | goto out_err; |
1277 | 1274 | ||
1278 | mutex_init(&irq_ptr->setup_mutex); | 1275 | mutex_init(&irq_ptr->setup_mutex); |
1279 | qdio_allocate_dbf(init_data, irq_ptr); | 1276 | if (qdio_allocate_dbf(init_data, irq_ptr)) |
1277 | goto out_rel; | ||
1280 | 1278 | ||
1281 | /* | 1279 | /* |
1282 | * Allocate a page for the chsc calls in qdio_establish. | 1280 | * Allocate a page for the chsc calls in qdio_establish. |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 8eec1653c9cc..69ef4f8cfac8 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -77,12 +77,12 @@ MODULE_ALIAS("z90crypt"); | |||
77 | * Module parameter | 77 | * Module parameter |
78 | */ | 78 | */ |
79 | int ap_domain_index = -1; /* Adjunct Processor Domain Index */ | 79 | int ap_domain_index = -1; /* Adjunct Processor Domain Index */ |
80 | module_param_named(domain, ap_domain_index, int, 0000); | 80 | module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP); |
81 | MODULE_PARM_DESC(domain, "domain index for ap devices"); | 81 | MODULE_PARM_DESC(domain, "domain index for ap devices"); |
82 | EXPORT_SYMBOL(ap_domain_index); | 82 | EXPORT_SYMBOL(ap_domain_index); |
83 | 83 | ||
84 | static int ap_thread_flag = 0; | 84 | static int ap_thread_flag = 0; |
85 | module_param_named(poll_thread, ap_thread_flag, int, 0000); | 85 | module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP); |
86 | MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off)."); | 86 | MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off)."); |
87 | 87 | ||
88 | static struct device *ap_root_device = NULL; | 88 | static struct device *ap_root_device = NULL; |
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 5222ebe15705..0e18c5dcd91f 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c | |||
@@ -356,7 +356,7 @@ struct zcrypt_ops *zcrypt_msgtype_request(unsigned char *name, int variant) | |||
356 | 356 | ||
357 | zops = __ops_lookup(name, variant); | 357 | zops = __ops_lookup(name, variant); |
358 | if (!zops) { | 358 | if (!zops) { |
359 | request_module(name); | 359 | request_module("%s", name); |
360 | zops = __ops_lookup(name, variant); | 360 | zops = __ops_lookup(name, variant); |
361 | } | 361 | } |
362 | if ((!zops) || (!try_module_get(zops->owner))) | 362 | if ((!zops) || (!try_module_get(zops->owner))) |