aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-10-23 03:10:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-10-23 03:10:25 -0400
commit320437af954cbe66478f1f5e8b34cb5a8d072191 (patch)
tree179940f87f305533380abbec5c0c5bd8a6147dbc /drivers
parent90338325a9cab8ff93359963e3a37be1c8907389 (diff)
parent8c071b0f19dfa230335d22ce56a8fab5bd20cedc (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: "Several last minute bug fixes. Two of them are on the larger side for rc7, the dasd format patch for older storage devices and the store-clock-fast patch where we have been to optimistic with an optimization" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/time: correct use of store clock fast s390/vmlogrdr: fix array access in vmlogrdr_open() s390/compat,signal: fix return value of copy_siginfo_(to|from)_user32() s390/dasd: check for availability of prefix command during format s390/mm,kvm: fix software dirty bits vs. kvm for old machines
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/block/dasd_eckd.c98
-rw-r--r--drivers/s390/char/sclp.c4
-rw-r--r--drivers/s390/char/vmlogrdr.c2
-rw-r--r--drivers/s390/cio/cio.c4
-rw-r--r--drivers/s390/cio/qdio_main.c10
5 files changed, 81 insertions, 37 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 5adb2042e824..cee7e2708a1f 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2077,6 +2077,7 @@ dasd_eckd_build_format(struct dasd_device *base,
2077 int intensity = 0; 2077 int intensity = 0;
2078 int r0_perm; 2078 int r0_perm;
2079 int nr_tracks; 2079 int nr_tracks;
2080 int use_prefix;
2080 2081
2081 startdev = dasd_alias_get_start_dev(base); 2082 startdev = dasd_alias_get_start_dev(base);
2082 if (!startdev) 2083 if (!startdev)
@@ -2106,28 +2107,46 @@ dasd_eckd_build_format(struct dasd_device *base,
2106 intensity = fdata->intensity; 2107 intensity = fdata->intensity;
2107 } 2108 }
2108 2109
2110 use_prefix = base_priv->features.feature[8] & 0x01;
2111
2109 switch (intensity) { 2112 switch (intensity) {
2110 case 0x00: /* Normal format */ 2113 case 0x00: /* Normal format */
2111 case 0x08: /* Normal format, use cdl. */ 2114 case 0x08: /* Normal format, use cdl. */
2112 cplength = 2 + (rpt*nr_tracks); 2115 cplength = 2 + (rpt*nr_tracks);
2113 datasize = sizeof(struct PFX_eckd_data) + 2116 if (use_prefix)
2114 sizeof(struct LO_eckd_data) + 2117 datasize = sizeof(struct PFX_eckd_data) +
2115 rpt * nr_tracks * sizeof(struct eckd_count); 2118 sizeof(struct LO_eckd_data) +
2119 rpt * nr_tracks * sizeof(struct eckd_count);
2120 else
2121 datasize = sizeof(struct DE_eckd_data) +
2122 sizeof(struct LO_eckd_data) +
2123 rpt * nr_tracks * sizeof(struct eckd_count);
2116 break; 2124 break;
2117 case 0x01: /* Write record zero and format track. */ 2125 case 0x01: /* Write record zero and format track. */
2118 case 0x09: /* Write record zero and format track, use cdl. */ 2126 case 0x09: /* Write record zero and format track, use cdl. */
2119 cplength = 2 + rpt * nr_tracks; 2127 cplength = 2 + rpt * nr_tracks;
2120 datasize = sizeof(struct PFX_eckd_data) + 2128 if (use_prefix)
2121 sizeof(struct LO_eckd_data) + 2129 datasize = sizeof(struct PFX_eckd_data) +
2122 sizeof(struct eckd_count) + 2130 sizeof(struct LO_eckd_data) +
2123 rpt * nr_tracks * sizeof(struct eckd_count); 2131 sizeof(struct eckd_count) +
2132 rpt * nr_tracks * sizeof(struct eckd_count);
2133 else
2134 datasize = sizeof(struct DE_eckd_data) +
2135 sizeof(struct LO_eckd_data) +
2136 sizeof(struct eckd_count) +
2137 rpt * nr_tracks * sizeof(struct eckd_count);
2124 break; 2138 break;
2125 case 0x04: /* Invalidate track. */ 2139 case 0x04: /* Invalidate track. */
2126 case 0x0c: /* Invalidate track, use cdl. */ 2140 case 0x0c: /* Invalidate track, use cdl. */
2127 cplength = 3; 2141 cplength = 3;
2128 datasize = sizeof(struct PFX_eckd_data) + 2142 if (use_prefix)
2129 sizeof(struct LO_eckd_data) + 2143 datasize = sizeof(struct PFX_eckd_data) +
2130 sizeof(struct eckd_count); 2144 sizeof(struct LO_eckd_data) +
2145 sizeof(struct eckd_count);
2146 else
2147 datasize = sizeof(struct DE_eckd_data) +
2148 sizeof(struct LO_eckd_data) +
2149 sizeof(struct eckd_count);
2131 break; 2150 break;
2132 default: 2151 default:
2133 dev_warn(&startdev->cdev->dev, 2152 dev_warn(&startdev->cdev->dev,
@@ -2147,14 +2166,25 @@ dasd_eckd_build_format(struct dasd_device *base,
2147 2166
2148 switch (intensity & ~0x08) { 2167 switch (intensity & ~0x08) {
2149 case 0x00: /* Normal format. */ 2168 case 0x00: /* Normal format. */
2150 prefix(ccw++, (struct PFX_eckd_data *) data, 2169 if (use_prefix) {
2151 fdata->start_unit, fdata->stop_unit, 2170 prefix(ccw++, (struct PFX_eckd_data *) data,
2152 DASD_ECKD_CCW_WRITE_CKD, base, startdev); 2171 fdata->start_unit, fdata->stop_unit,
2153 /* grant subsystem permission to format R0 */ 2172 DASD_ECKD_CCW_WRITE_CKD, base, startdev);
2154 if (r0_perm) 2173 /* grant subsystem permission to format R0 */
2155 ((struct PFX_eckd_data *)data) 2174 if (r0_perm)
2156 ->define_extent.ga_extended |= 0x04; 2175 ((struct PFX_eckd_data *)data)
2157 data += sizeof(struct PFX_eckd_data); 2176 ->define_extent.ga_extended |= 0x04;
2177 data += sizeof(struct PFX_eckd_data);
2178 } else {
2179 define_extent(ccw++, (struct DE_eckd_data *) data,
2180 fdata->start_unit, fdata->stop_unit,
2181 DASD_ECKD_CCW_WRITE_CKD, startdev);
2182 /* grant subsystem permission to format R0 */
2183 if (r0_perm)
2184 ((struct DE_eckd_data *) data)
2185 ->ga_extended |= 0x04;
2186 data += sizeof(struct DE_eckd_data);
2187 }
2158 ccw[-1].flags |= CCW_FLAG_CC; 2188 ccw[-1].flags |= CCW_FLAG_CC;
2159 locate_record(ccw++, (struct LO_eckd_data *) data, 2189 locate_record(ccw++, (struct LO_eckd_data *) data,
2160 fdata->start_unit, 0, rpt*nr_tracks, 2190 fdata->start_unit, 0, rpt*nr_tracks,
@@ -2163,11 +2193,18 @@ dasd_eckd_build_format(struct dasd_device *base,
2163 data += sizeof(struct LO_eckd_data); 2193 data += sizeof(struct LO_eckd_data);
2164 break; 2194 break;
2165 case 0x01: /* Write record zero + format track. */ 2195 case 0x01: /* Write record zero + format track. */
2166 prefix(ccw++, (struct PFX_eckd_data *) data, 2196 if (use_prefix) {
2167 fdata->start_unit, fdata->stop_unit, 2197 prefix(ccw++, (struct PFX_eckd_data *) data,
2168 DASD_ECKD_CCW_WRITE_RECORD_ZERO, 2198 fdata->start_unit, fdata->stop_unit,
2169 base, startdev); 2199 DASD_ECKD_CCW_WRITE_RECORD_ZERO,
2170 data += sizeof(struct PFX_eckd_data); 2200 base, startdev);
2201 data += sizeof(struct PFX_eckd_data);
2202 } else {
2203 define_extent(ccw++, (struct DE_eckd_data *) data,
2204 fdata->start_unit, fdata->stop_unit,
2205 DASD_ECKD_CCW_WRITE_RECORD_ZERO, startdev);
2206 data += sizeof(struct DE_eckd_data);
2207 }
2171 ccw[-1].flags |= CCW_FLAG_CC; 2208 ccw[-1].flags |= CCW_FLAG_CC;
2172 locate_record(ccw++, (struct LO_eckd_data *) data, 2209 locate_record(ccw++, (struct LO_eckd_data *) data,
2173 fdata->start_unit, 0, rpt * nr_tracks + 1, 2210 fdata->start_unit, 0, rpt * nr_tracks + 1,
@@ -2176,10 +2213,17 @@ dasd_eckd_build_format(struct dasd_device *base,
2176 data += sizeof(struct LO_eckd_data); 2213 data += sizeof(struct LO_eckd_data);
2177 break; 2214 break;
2178 case 0x04: /* Invalidate track. */ 2215 case 0x04: /* Invalidate track. */
2179 prefix(ccw++, (struct PFX_eckd_data *) data, 2216 if (use_prefix) {
2180 fdata->start_unit, fdata->stop_unit, 2217 prefix(ccw++, (struct PFX_eckd_data *) data,
2181 DASD_ECKD_CCW_WRITE_CKD, base, startdev); 2218 fdata->start_unit, fdata->stop_unit,
2182 data += sizeof(struct PFX_eckd_data); 2219 DASD_ECKD_CCW_WRITE_CKD, base, startdev);
2220 data += sizeof(struct PFX_eckd_data);
2221 } else {
2222 define_extent(ccw++, (struct DE_eckd_data *) data,
2223 fdata->start_unit, fdata->stop_unit,
2224 DASD_ECKD_CCW_WRITE_CKD, startdev);
2225 data += sizeof(struct DE_eckd_data);
2226 }
2183 ccw[-1].flags |= CCW_FLAG_CC; 2227 ccw[-1].flags |= CCW_FLAG_CC;
2184 locate_record(ccw++, (struct LO_eckd_data *) data, 2228 locate_record(ccw++, (struct LO_eckd_data *) data,
2185 fdata->start_unit, 0, 1, 2229 fdata->start_unit, 0, 1,
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index a3aa374799dc..1fe264379e0d 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -486,7 +486,7 @@ sclp_sync_wait(void)
486 timeout = 0; 486 timeout = 0;
487 if (timer_pending(&sclp_request_timer)) { 487 if (timer_pending(&sclp_request_timer)) {
488 /* Get timeout TOD value */ 488 /* Get timeout TOD value */
489 timeout = get_tod_clock() + 489 timeout = get_tod_clock_fast() +
490 sclp_tod_from_jiffies(sclp_request_timer.expires - 490 sclp_tod_from_jiffies(sclp_request_timer.expires -
491 jiffies); 491 jiffies);
492 } 492 }
@@ -508,7 +508,7 @@ sclp_sync_wait(void)
508 while (sclp_running_state != sclp_running_state_idle) { 508 while (sclp_running_state != sclp_running_state_idle) {
509 /* Check for expired request timer */ 509 /* Check for expired request timer */
510 if (timer_pending(&sclp_request_timer) && 510 if (timer_pending(&sclp_request_timer) &&
511 get_tod_clock() > timeout && 511 get_tod_clock_fast() > timeout &&
512 del_timer(&sclp_request_timer)) 512 del_timer(&sclp_request_timer))
513 sclp_request_timer.function(sclp_request_timer.data); 513 sclp_request_timer.function(sclp_request_timer.data);
514 cpu_relax(); 514 cpu_relax();
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 9b3a24e8d3a0..cf31d3321dab 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -313,7 +313,7 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp)
313 int ret; 313 int ret;
314 314
315 dev_num = iminor(inode); 315 dev_num = iminor(inode);
316 if (dev_num > MAXMINOR) 316 if (dev_num >= MAXMINOR)
317 return -ENODEV; 317 return -ENODEV;
318 logptr = &sys_ser[dev_num]; 318 logptr = &sys_ser[dev_num];
319 319
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index d7da67a31c77..88e35d85d205 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -878,9 +878,9 @@ static void css_reset(void)
878 atomic_inc(&chpid_reset_count); 878 atomic_inc(&chpid_reset_count);
879 } 879 }
880 /* Wait for machine check for all channel paths. */ 880 /* Wait for machine check for all channel paths. */
881 timeout = get_tod_clock() + (RCHP_TIMEOUT << 12); 881 timeout = get_tod_clock_fast() + (RCHP_TIMEOUT << 12);
882 while (atomic_read(&chpid_reset_count) != 0) { 882 while (atomic_read(&chpid_reset_count) != 0) {
883 if (get_tod_clock() > timeout) 883 if (get_tod_clock_fast() > timeout)
884 break; 884 break;
885 cpu_relax(); 885 cpu_relax();
886 } 886 }
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 8ed52aa49122..bbd3e511c771 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -338,10 +338,10 @@ again:
338 retries++; 338 retries++;
339 339
340 if (!start_time) { 340 if (!start_time) {
341 start_time = get_tod_clock(); 341 start_time = get_tod_clock_fast();
342 goto again; 342 goto again;
343 } 343 }
344 if ((get_tod_clock() - start_time) < QDIO_BUSY_BIT_PATIENCE) 344 if (get_tod_clock_fast() - start_time < QDIO_BUSY_BIT_PATIENCE)
345 goto again; 345 goto again;
346 } 346 }
347 if (retries) { 347 if (retries) {
@@ -504,7 +504,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
504 int count, stop; 504 int count, stop;
505 unsigned char state = 0; 505 unsigned char state = 0;
506 506
507 q->timestamp = get_tod_clock(); 507 q->timestamp = get_tod_clock_fast();
508 508
509 /* 509 /*
510 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved 510 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved
@@ -595,7 +595,7 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
595 * At this point we know, that inbound first_to_check 595 * At this point we know, that inbound first_to_check
596 * has (probably) not moved (see qdio_inbound_processing). 596 * has (probably) not moved (see qdio_inbound_processing).
597 */ 597 */
598 if (get_tod_clock() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) { 598 if (get_tod_clock_fast() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) {
599 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in done:%02x", 599 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in done:%02x",
600 q->first_to_check); 600 q->first_to_check);
601 return 1; 601 return 1;
@@ -728,7 +728,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
728 int count, stop; 728 int count, stop;
729 unsigned char state = 0; 729 unsigned char state = 0;
730 730
731 q->timestamp = get_tod_clock(); 731 q->timestamp = get_tod_clock_fast();
732 732
733 if (need_siga_sync(q)) 733 if (need_siga_sync(q))
734 if (((queue_type(q) != QDIO_IQDIO_QFMT) && 734 if (((queue_type(q) != QDIO_IQDIO_QFMT) &&