diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/block/dasd.c | 9 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 9 | ||||
-rw-r--r-- | drivers/s390/block/dasd_proc.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/sclp_async.c | 9 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 2 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.c | 12 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 21 |
7 files changed, 42 insertions, 24 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 432444af7ee4..a1d3ddba99cc 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/debugfs.h> | 25 | #include <linux/debugfs.h> |
26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
27 | #include <linux/vmalloc.h> | ||
27 | 28 | ||
28 | #include <asm/ccwdev.h> | 29 | #include <asm/ccwdev.h> |
29 | #include <asm/ebcdic.h> | 30 | #include <asm/ebcdic.h> |
@@ -888,11 +889,11 @@ char *dasd_get_user_string(const char __user *user_buf, size_t user_len) | |||
888 | { | 889 | { |
889 | char *buffer; | 890 | char *buffer; |
890 | 891 | ||
891 | buffer = kmalloc(user_len + 1, GFP_KERNEL); | 892 | buffer = vmalloc(user_len + 1); |
892 | if (buffer == NULL) | 893 | if (buffer == NULL) |
893 | return ERR_PTR(-ENOMEM); | 894 | return ERR_PTR(-ENOMEM); |
894 | if (copy_from_user(buffer, user_buf, user_len) != 0) { | 895 | if (copy_from_user(buffer, user_buf, user_len) != 0) { |
895 | kfree(buffer); | 896 | vfree(buffer); |
896 | return ERR_PTR(-EFAULT); | 897 | return ERR_PTR(-EFAULT); |
897 | } | 898 | } |
898 | /* got the string, now strip linefeed. */ | 899 | /* got the string, now strip linefeed. */ |
@@ -930,7 +931,7 @@ static ssize_t dasd_stats_write(struct file *file, | |||
930 | dasd_profile_off(prof); | 931 | dasd_profile_off(prof); |
931 | } else | 932 | } else |
932 | rc = -EINVAL; | 933 | rc = -EINVAL; |
933 | kfree(buffer); | 934 | vfree(buffer); |
934 | return rc; | 935 | return rc; |
935 | } | 936 | } |
936 | 937 | ||
@@ -1042,7 +1043,7 @@ static ssize_t dasd_stats_global_write(struct file *file, | |||
1042 | dasd_global_profile_level = DASD_PROFILE_OFF; | 1043 | dasd_global_profile_level = DASD_PROFILE_OFF; |
1043 | } else | 1044 | } else |
1044 | rc = -EINVAL; | 1045 | rc = -EINVAL; |
1045 | kfree(buffer); | 1046 | vfree(buffer); |
1046 | return rc; | 1047 | return rc; |
1047 | } | 1048 | } |
1048 | 1049 | ||
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 30fb979d684d..6e835c9fdfcb 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1461,6 +1461,15 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1461 | "Read device characteristic failed, rc=%d", rc); | 1461 | "Read device characteristic failed, rc=%d", rc); |
1462 | goto out_err3; | 1462 | goto out_err3; |
1463 | } | 1463 | } |
1464 | |||
1465 | if ((device->features & DASD_FEATURE_USERAW) && | ||
1466 | !(private->rdc_data.facilities.RT_in_LR)) { | ||
1467 | dev_err(&device->cdev->dev, "The storage server does not " | ||
1468 | "support raw-track access\n"); | ||
1469 | rc = -EINVAL; | ||
1470 | goto out_err3; | ||
1471 | } | ||
1472 | |||
1464 | /* find the valid cylinder size */ | 1473 | /* find the valid cylinder size */ |
1465 | if (private->rdc_data.no_cyl == LV_COMPAT_CYL && | 1474 | if (private->rdc_data.no_cyl == LV_COMPAT_CYL && |
1466 | private->rdc_data.long_no_cyl) | 1475 | private->rdc_data.long_no_cyl) |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 6c3c5364d082..e12989fff4ff 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -312,14 +312,14 @@ static ssize_t dasd_stats_proc_write(struct file *file, | |||
312 | pr_info("The statistics have been reset\n"); | 312 | pr_info("The statistics have been reset\n"); |
313 | } else | 313 | } else |
314 | goto out_parse_error; | 314 | goto out_parse_error; |
315 | kfree(buffer); | 315 | vfree(buffer); |
316 | return user_len; | 316 | return user_len; |
317 | out_parse_error: | 317 | out_parse_error: |
318 | rc = -EINVAL; | 318 | rc = -EINVAL; |
319 | pr_warning("%s is not a supported value for /proc/dasd/statistics\n", | 319 | pr_warning("%s is not a supported value for /proc/dasd/statistics\n", |
320 | str); | 320 | str); |
321 | out_error: | 321 | out_error: |
322 | kfree(buffer); | 322 | vfree(buffer); |
323 | return rc; | 323 | return rc; |
324 | #else | 324 | #else |
325 | pr_warning("/proc/dasd/statistics: is not activated in this kernel\n"); | 325 | pr_warning("/proc/dasd/statistics: is not activated in this kernel\n"); |
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c index 7ad30e72f868..5f9f929e891c 100644 --- a/drivers/s390/char/sclp_async.c +++ b/drivers/s390/char/sclp_async.c | |||
@@ -82,12 +82,9 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write, | |||
82 | return -EFAULT; | 82 | return -EFAULT; |
83 | } else { | 83 | } else { |
84 | len = *count; | 84 | len = *count; |
85 | rc = copy_from_user(buf, buffer, sizeof(buf)); | 85 | rc = kstrtoul_from_user(buffer, len, 0, &val); |
86 | if (rc != 0) | 86 | if (rc) |
87 | return -EFAULT; | 87 | return rc; |
88 | buf[sizeof(buf) - 1] = '\0'; | ||
89 | if (strict_strtoul(buf, 0, &val) != 0) | ||
90 | return -EINVAL; | ||
91 | if (val != 0 && val != 1) | 88 | if (val != 0 && val != 1) |
92 | return -EINVAL; | 89 | return -EINVAL; |
93 | callhome_enabled = val; | 90 | callhome_enabled = val; |
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 7bc643f3f5ab..e5c966462c5a 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #include "chsc.h" | 14 | #include "chsc.h" |
15 | 15 | ||
16 | #define QDIO_BUSY_BIT_PATIENCE (100 << 12) /* 100 microseconds */ | 16 | #define QDIO_BUSY_BIT_PATIENCE (100 << 12) /* 100 microseconds */ |
17 | #define QDIO_BUSY_BIT_RETRY_DELAY 10 /* 10 milliseconds */ | ||
18 | #define QDIO_BUSY_BIT_RETRIES 1000 /* = 10s retry time */ | ||
17 | #define QDIO_INPUT_THRESHOLD (500 << 12) /* 500 microseconds */ | 19 | #define QDIO_INPUT_THRESHOLD (500 << 12) /* 500 microseconds */ |
18 | 20 | ||
19 | /* | 21 | /* |
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index f8b03a636e49..0e615cb912d0 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c | |||
@@ -188,19 +188,13 @@ static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf, | |||
188 | struct qdio_irq *irq_ptr = seq->private; | 188 | struct qdio_irq *irq_ptr = seq->private; |
189 | struct qdio_q *q; | 189 | struct qdio_q *q; |
190 | unsigned long val; | 190 | unsigned long val; |
191 | char buf[8]; | ||
192 | int ret, i; | 191 | int ret, i; |
193 | 192 | ||
194 | if (!irq_ptr) | 193 | if (!irq_ptr) |
195 | return 0; | 194 | return 0; |
196 | if (count >= sizeof(buf)) | 195 | |
197 | return -EINVAL; | 196 | ret = kstrtoul_from_user(ubuf, count, 10, &val); |
198 | if (copy_from_user(&buf, ubuf, count)) | 197 | if (ret) |
199 | return -EFAULT; | ||
200 | buf[count] = 0; | ||
201 | |||
202 | ret = strict_strtoul(buf, 10, &val); | ||
203 | if (ret < 0) | ||
204 | return ret; | 198 | return ret; |
205 | 199 | ||
206 | switch (val) { | 200 | switch (val) { |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index e58169c32474..288c9140290e 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -313,7 +313,7 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit) | |||
313 | unsigned long schid = *((u32 *) &q->irq_ptr->schid); | 313 | unsigned long schid = *((u32 *) &q->irq_ptr->schid); |
314 | unsigned int fc = QDIO_SIGA_WRITE; | 314 | unsigned int fc = QDIO_SIGA_WRITE; |
315 | u64 start_time = 0; | 315 | u64 start_time = 0; |
316 | int cc; | 316 | int retries = 0, cc; |
317 | 317 | ||
318 | if (is_qebsm(q)) { | 318 | if (is_qebsm(q)) { |
319 | schid = q->irq_ptr->sch_token; | 319 | schid = q->irq_ptr->sch_token; |
@@ -325,6 +325,7 @@ again: | |||
325 | /* hipersocket busy condition */ | 325 | /* hipersocket busy condition */ |
326 | if (unlikely(*busy_bit)) { | 326 | if (unlikely(*busy_bit)) { |
327 | WARN_ON(queue_type(q) != QDIO_IQDIO_QFMT || cc != 2); | 327 | WARN_ON(queue_type(q) != QDIO_IQDIO_QFMT || cc != 2); |
328 | retries++; | ||
328 | 329 | ||
329 | if (!start_time) { | 330 | if (!start_time) { |
330 | start_time = get_clock(); | 331 | start_time = get_clock(); |
@@ -333,6 +334,11 @@ again: | |||
333 | if ((get_clock() - start_time) < QDIO_BUSY_BIT_PATIENCE) | 334 | if ((get_clock() - start_time) < QDIO_BUSY_BIT_PATIENCE) |
334 | goto again; | 335 | goto again; |
335 | } | 336 | } |
337 | if (retries) { | ||
338 | DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, | ||
339 | "%4x cc2 BB1:%1d", SCH_NO(q), q->nr); | ||
340 | DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "count:%u", retries); | ||
341 | } | ||
336 | return cc; | 342 | return cc; |
337 | } | 343 | } |
338 | 344 | ||
@@ -728,13 +734,14 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q) | |||
728 | 734 | ||
729 | static int qdio_kick_outbound_q(struct qdio_q *q) | 735 | static int qdio_kick_outbound_q(struct qdio_q *q) |
730 | { | 736 | { |
737 | int retries = 0, cc; | ||
731 | unsigned int busy_bit; | 738 | unsigned int busy_bit; |
732 | int cc; | ||
733 | 739 | ||
734 | if (!need_siga_out(q)) | 740 | if (!need_siga_out(q)) |
735 | return 0; | 741 | return 0; |
736 | 742 | ||
737 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); | 743 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); |
744 | retry: | ||
738 | qperf_inc(q, siga_write); | 745 | qperf_inc(q, siga_write); |
739 | 746 | ||
740 | cc = qdio_siga_output(q, &busy_bit); | 747 | cc = qdio_siga_output(q, &busy_bit); |
@@ -743,7 +750,11 @@ static int qdio_kick_outbound_q(struct qdio_q *q) | |||
743 | break; | 750 | break; |
744 | case 2: | 751 | case 2: |
745 | if (busy_bit) { | 752 | if (busy_bit) { |
746 | DBF_ERROR("%4x cc2 REP:%1d", SCH_NO(q), q->nr); | 753 | while (++retries < QDIO_BUSY_BIT_RETRIES) { |
754 | mdelay(QDIO_BUSY_BIT_RETRY_DELAY); | ||
755 | goto retry; | ||
756 | } | ||
757 | DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr); | ||
747 | cc |= QDIO_ERROR_SIGA_BUSY; | 758 | cc |= QDIO_ERROR_SIGA_BUSY; |
748 | } else | 759 | } else |
749 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); | 760 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); |
@@ -753,6 +764,10 @@ static int qdio_kick_outbound_q(struct qdio_q *q) | |||
753 | DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); | 764 | DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); |
754 | break; | 765 | break; |
755 | } | 766 | } |
767 | if (retries) { | ||
768 | DBF_ERROR("%4x cc2 BB2:%1d", SCH_NO(q), q->nr); | ||
769 | DBF_ERROR("count:%u", retries); | ||
770 | } | ||
756 | return cc; | 771 | return cc; |
757 | } | 772 | } |
758 | 773 | ||