aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/block/dasd.c9
-rw-r--r--drivers/s390/block/dasd_eckd.c9
-rw-r--r--drivers/s390/block/dasd_proc.c4
-rw-r--r--drivers/s390/char/sclp_async.c9
-rw-r--r--drivers/s390/cio/qdio.h2
-rw-r--r--drivers/s390/cio/qdio_debug.c12
-rw-r--r--drivers/s390/cio/qdio_main.c21
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;
317out_parse_error: 317out_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);
321out_error: 321out_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
729static int qdio_kick_outbound_q(struct qdio_q *q) 735static 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);
744retry:
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