aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c115
-rw-r--r--drivers/s390/block/dasd_devmap.c97
-rw-r--r--drivers/s390/block/dasd_diag.c8
-rw-r--r--drivers/s390/block/dasd_eckd.c17
-rw-r--r--drivers/s390/block/dasd_erp.c8
-rw-r--r--drivers/s390/block/dasd_fba.c10
-rw-r--r--drivers/s390/block/dasd_int.h10
-rw-r--r--drivers/s390/block/dasd_ioctl.c59
-rw-r--r--drivers/s390/char/Makefile2
-rw-r--r--drivers/s390/char/sclp.c86
-rw-r--r--drivers/s390/char/sclp.h7
-rw-r--r--drivers/s390/char/sclp_cmd.c20
-rw-r--r--drivers/s390/char/sclp_con.c31
-rw-r--r--drivers/s390/char/sclp_ctl.c144
-rw-r--r--drivers/s390/char/sclp_vt220.c39
-rw-r--r--drivers/s390/char/tape_class.c2
-rw-r--r--drivers/s390/char/vmwatchdog.c5
-rw-r--r--drivers/s390/cio/airq.c167
-rw-r--r--drivers/s390/cio/chsc.c60
-rw-r--r--drivers/s390/cio/chsc.h44
-rw-r--r--drivers/s390/cio/chsc_sch.c155
-rw-r--r--drivers/s390/cio/cio.c68
-rw-r--r--drivers/s390/cio/qdio.h34
-rw-r--r--drivers/s390/cio/qdio_main.c44
-rw-r--r--drivers/s390/cio/qdio_setup.c47
-rw-r--r--drivers/s390/cio/qdio_thinint.c79
-rw-r--r--drivers/s390/crypto/ap_bus.c64
-rw-r--r--drivers/s390/net/claw.c2
-rw-r--r--drivers/s390/net/ctcm_main.c2
-rw-r--r--drivers/s390/net/lcs.c2
-rw-r--r--drivers/s390/net/qeth_core_main.c2
31 files changed, 1034 insertions, 396 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index d72a9216ee2e..17150a778984 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -38,9 +38,6 @@
38 */ 38 */
39#define DASD_CHANQ_MAX_SIZE 4 39#define DASD_CHANQ_MAX_SIZE 4
40 40
41#define DASD_SLEEPON_START_TAG (void *) 1
42#define DASD_SLEEPON_END_TAG (void *) 2
43
44/* 41/*
45 * SECTION: exported variables of dasd.c 42 * SECTION: exported variables of dasd.c
46 */ 43 */
@@ -1787,11 +1784,11 @@ static void __dasd_device_process_ccw_queue(struct dasd_device *device,
1787 list_for_each_safe(l, n, &device->ccw_queue) { 1784 list_for_each_safe(l, n, &device->ccw_queue) {
1788 cqr = list_entry(l, struct dasd_ccw_req, devlist); 1785 cqr = list_entry(l, struct dasd_ccw_req, devlist);
1789 1786
1790 /* Stop list processing at the first non-final request. */ 1787 /* Skip any non-final request. */
1791 if (cqr->status == DASD_CQR_QUEUED || 1788 if (cqr->status == DASD_CQR_QUEUED ||
1792 cqr->status == DASD_CQR_IN_IO || 1789 cqr->status == DASD_CQR_IN_IO ||
1793 cqr->status == DASD_CQR_CLEAR_PENDING) 1790 cqr->status == DASD_CQR_CLEAR_PENDING)
1794 break; 1791 continue;
1795 if (cqr->status == DASD_CQR_ERROR) { 1792 if (cqr->status == DASD_CQR_ERROR) {
1796 __dasd_device_recovery(device, cqr); 1793 __dasd_device_recovery(device, cqr);
1797 } 1794 }
@@ -2183,7 +2180,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
2183 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && 2180 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
2184 (!dasd_eer_enabled(device))) { 2181 (!dasd_eer_enabled(device))) {
2185 cqr->status = DASD_CQR_FAILED; 2182 cqr->status = DASD_CQR_FAILED;
2186 cqr->intrc = -EAGAIN; 2183 cqr->intrc = -ENOLINK;
2187 continue; 2184 continue;
2188 } 2185 }
2189 /* Don't try to start requests if device is stopped */ 2186 /* Don't try to start requests if device is stopped */
@@ -2402,8 +2399,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
2402 * Cancels a request that was started with dasd_sleep_on_req. 2399 * Cancels a request that was started with dasd_sleep_on_req.
2403 * This is useful to timeout requests. The request will be 2400 * This is useful to timeout requests. The request will be
2404 * terminated if it is currently in i/o. 2401 * terminated if it is currently in i/o.
2405 * Returns 1 if the request has been terminated. 2402 * Returns 0 if request termination was successful
2406 * 0 if there was no need to terminate the request (not started yet)
2407 * negative error code if termination failed 2403 * negative error code if termination failed
2408 * Cancellation of a request is an asynchronous operation! The calling 2404 * Cancellation of a request is an asynchronous operation! The calling
2409 * function has to wait until the request is properly returned via callback. 2405 * function has to wait until the request is properly returned via callback.
@@ -2440,7 +2436,6 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
2440 return rc; 2436 return rc;
2441} 2437}
2442 2438
2443
2444/* 2439/*
2445 * SECTION: Operations of the dasd_block layer. 2440 * SECTION: Operations of the dasd_block layer.
2446 */ 2441 */
@@ -2537,6 +2532,16 @@ static void __dasd_process_request_queue(struct dasd_block *block)
2537 __blk_end_request_all(req, -EIO); 2532 __blk_end_request_all(req, -EIO);
2538 continue; 2533 continue;
2539 } 2534 }
2535 if (test_bit(DASD_FLAG_ABORTALL, &basedev->flags) &&
2536 (basedev->features & DASD_FEATURE_FAILFAST ||
2537 blk_noretry_request(req))) {
2538 DBF_DEV_EVENT(DBF_ERR, basedev,
2539 "Rejecting failfast request %p",
2540 req);
2541 blk_start_request(req);
2542 __blk_end_request_all(req, -ETIMEDOUT);
2543 continue;
2544 }
2540 cqr = basedev->discipline->build_cp(basedev, block, req); 2545 cqr = basedev->discipline->build_cp(basedev, block, req);
2541 if (IS_ERR(cqr)) { 2546 if (IS_ERR(cqr)) {
2542 if (PTR_ERR(cqr) == -EBUSY) 2547 if (PTR_ERR(cqr) == -EBUSY)
@@ -2575,8 +2580,10 @@ static void __dasd_process_request_queue(struct dasd_block *block)
2575 */ 2580 */
2576 cqr->callback_data = (void *) req; 2581 cqr->callback_data = (void *) req;
2577 cqr->status = DASD_CQR_FILLED; 2582 cqr->status = DASD_CQR_FILLED;
2583 req->completion_data = cqr;
2578 blk_start_request(req); 2584 blk_start_request(req);
2579 list_add_tail(&cqr->blocklist, &block->ccw_queue); 2585 list_add_tail(&cqr->blocklist, &block->ccw_queue);
2586 INIT_LIST_HEAD(&cqr->devlist);
2580 dasd_profile_start(block, cqr, req); 2587 dasd_profile_start(block, cqr, req);
2581 } 2588 }
2582} 2589}
@@ -2590,8 +2597,17 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr)
2590 req = (struct request *) cqr->callback_data; 2597 req = (struct request *) cqr->callback_data;
2591 dasd_profile_end(cqr->block, cqr, req); 2598 dasd_profile_end(cqr->block, cqr, req);
2592 status = cqr->block->base->discipline->free_cp(cqr, req); 2599 status = cqr->block->base->discipline->free_cp(cqr, req);
2593 if (status <= 0) 2600 if (status < 0)
2594 error = status ? status : -EIO; 2601 error = status;
2602 else if (status == 0) {
2603 if (cqr->intrc == -EPERM)
2604 error = -EBADE;
2605 else if (cqr->intrc == -ENOLINK ||
2606 cqr->intrc == -ETIMEDOUT)
2607 error = cqr->intrc;
2608 else
2609 error = -EIO;
2610 }
2595 __blk_end_request_all(req, error); 2611 __blk_end_request_all(req, error);
2596} 2612}
2597 2613
@@ -2692,6 +2708,7 @@ static void __dasd_block_start_head(struct dasd_block *block)
2692 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && 2708 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
2693 (!dasd_eer_enabled(block->base))) { 2709 (!dasd_eer_enabled(block->base))) {
2694 cqr->status = DASD_CQR_FAILED; 2710 cqr->status = DASD_CQR_FAILED;
2711 cqr->intrc = -ENOLINK;
2695 dasd_schedule_block_bh(block); 2712 dasd_schedule_block_bh(block);
2696 continue; 2713 continue;
2697 } 2714 }
@@ -2864,6 +2881,82 @@ static void do_dasd_request(struct request_queue *queue)
2864} 2881}
2865 2882
2866/* 2883/*
2884 * Block timeout callback, called from the block layer
2885 *
2886 * request_queue lock is held on entry.
2887 *
2888 * Return values:
2889 * BLK_EH_RESET_TIMER if the request should be left running
2890 * BLK_EH_NOT_HANDLED if the request is handled or terminated
2891 * by the driver.
2892 */
2893enum blk_eh_timer_return dasd_times_out(struct request *req)
2894{
2895 struct dasd_ccw_req *cqr = req->completion_data;
2896 struct dasd_block *block = req->q->queuedata;
2897 struct dasd_device *device;
2898 int rc = 0;
2899
2900 if (!cqr)
2901 return BLK_EH_NOT_HANDLED;
2902
2903 device = cqr->startdev ? cqr->startdev : block->base;
2904 if (!device->blk_timeout)
2905 return BLK_EH_RESET_TIMER;
2906 DBF_DEV_EVENT(DBF_WARNING, device,
2907 " dasd_times_out cqr %p status %x",
2908 cqr, cqr->status);
2909
2910 spin_lock(&block->queue_lock);
2911 spin_lock(get_ccwdev_lock(device->cdev));
2912 cqr->retries = -1;
2913 cqr->intrc = -ETIMEDOUT;
2914 if (cqr->status >= DASD_CQR_QUEUED) {
2915 spin_unlock(get_ccwdev_lock(device->cdev));
2916 rc = dasd_cancel_req(cqr);
2917 } else if (cqr->status == DASD_CQR_FILLED ||
2918 cqr->status == DASD_CQR_NEED_ERP) {
2919 cqr->status = DASD_CQR_TERMINATED;
2920 spin_unlock(get_ccwdev_lock(device->cdev));
2921 } else if (cqr->status == DASD_CQR_IN_ERP) {
2922 struct dasd_ccw_req *searchcqr, *nextcqr, *tmpcqr;
2923
2924 list_for_each_entry_safe(searchcqr, nextcqr,
2925 &block->ccw_queue, blocklist) {
2926 tmpcqr = searchcqr;
2927 while (tmpcqr->refers)
2928 tmpcqr = tmpcqr->refers;
2929 if (tmpcqr != cqr)
2930 continue;
2931 /* searchcqr is an ERP request for cqr */
2932 searchcqr->retries = -1;
2933 searchcqr->intrc = -ETIMEDOUT;
2934 if (searchcqr->status >= DASD_CQR_QUEUED) {
2935 spin_unlock(get_ccwdev_lock(device->cdev));
2936 rc = dasd_cancel_req(searchcqr);
2937 spin_lock(get_ccwdev_lock(device->cdev));
2938 } else if ((searchcqr->status == DASD_CQR_FILLED) ||
2939 (searchcqr->status == DASD_CQR_NEED_ERP)) {
2940 searchcqr->status = DASD_CQR_TERMINATED;
2941 rc = 0;
2942 } else if (searchcqr->status == DASD_CQR_IN_ERP) {
2943 /*
2944 * Shouldn't happen; most recent ERP
2945 * request is at the front of queue
2946 */
2947 continue;
2948 }
2949 break;
2950 }
2951 spin_unlock(get_ccwdev_lock(device->cdev));
2952 }
2953 dasd_schedule_block_bh(block);
2954 spin_unlock(&block->queue_lock);
2955
2956 return rc ? BLK_EH_RESET_TIMER : BLK_EH_NOT_HANDLED;
2957}
2958
2959/*
2867 * Allocate and initialize request queue and default I/O scheduler. 2960 * Allocate and initialize request queue and default I/O scheduler.
2868 */ 2961 */
2869static int dasd_alloc_queue(struct dasd_block *block) 2962static int dasd_alloc_queue(struct dasd_block *block)
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index a71bb8aaca1d..58bc6eb49de1 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -1240,6 +1240,101 @@ dasd_expires_store(struct device *dev, struct device_attribute *attr,
1240 1240
1241static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); 1241static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
1242 1242
1243static ssize_t
1244dasd_retries_show(struct device *dev, struct device_attribute *attr, char *buf)
1245{
1246 struct dasd_device *device;
1247 int len;
1248
1249 device = dasd_device_from_cdev(to_ccwdev(dev));
1250 if (IS_ERR(device))
1251 return -ENODEV;
1252 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_retries);
1253 dasd_put_device(device);
1254 return len;
1255}
1256
1257static ssize_t
1258dasd_retries_store(struct device *dev, struct device_attribute *attr,
1259 const char *buf, size_t count)
1260{
1261 struct dasd_device *device;
1262 unsigned long val;
1263
1264 device = dasd_device_from_cdev(to_ccwdev(dev));
1265 if (IS_ERR(device))
1266 return -ENODEV;
1267
1268 if ((strict_strtoul(buf, 10, &val) != 0) ||
1269 (val > DASD_RETRIES_MAX)) {
1270 dasd_put_device(device);
1271 return -EINVAL;
1272 }
1273
1274 if (val)
1275 device->default_retries = val;
1276
1277 dasd_put_device(device);
1278 return count;
1279}
1280
1281static DEVICE_ATTR(retries, 0644, dasd_retries_show, dasd_retries_store);
1282
1283static ssize_t
1284dasd_timeout_show(struct device *dev, struct device_attribute *attr,
1285 char *buf)
1286{
1287 struct dasd_device *device;
1288 int len;
1289
1290 device = dasd_device_from_cdev(to_ccwdev(dev));
1291 if (IS_ERR(device))
1292 return -ENODEV;
1293 len = snprintf(buf, PAGE_SIZE, "%lu\n", device->blk_timeout);
1294 dasd_put_device(device);
1295 return len;
1296}
1297
1298static ssize_t
1299dasd_timeout_store(struct device *dev, struct device_attribute *attr,
1300 const char *buf, size_t count)
1301{
1302 struct dasd_device *device;
1303 struct request_queue *q;
1304 unsigned long val, flags;
1305
1306 device = dasd_device_from_cdev(to_ccwdev(dev));
1307 if (IS_ERR(device) || !device->block)
1308 return -ENODEV;
1309
1310 if ((strict_strtoul(buf, 10, &val) != 0) ||
1311 val > UINT_MAX / HZ) {
1312 dasd_put_device(device);
1313 return -EINVAL;
1314 }
1315 q = device->block->request_queue;
1316 if (!q) {
1317 dasd_put_device(device);
1318 return -ENODEV;
1319 }
1320 spin_lock_irqsave(&device->block->request_queue_lock, flags);
1321 if (!val)
1322 blk_queue_rq_timed_out(q, NULL);
1323 else
1324 blk_queue_rq_timed_out(q, dasd_times_out);
1325
1326 device->blk_timeout = val;
1327
1328 blk_queue_rq_timeout(q, device->blk_timeout * HZ);
1329 spin_unlock_irqrestore(&device->block->request_queue_lock, flags);
1330
1331 dasd_put_device(device);
1332 return count;
1333}
1334
1335static DEVICE_ATTR(timeout, 0644,
1336 dasd_timeout_show, dasd_timeout_store);
1337
1243static ssize_t dasd_reservation_policy_show(struct device *dev, 1338static ssize_t dasd_reservation_policy_show(struct device *dev,
1244 struct device_attribute *attr, 1339 struct device_attribute *attr,
1245 char *buf) 1340 char *buf)
@@ -1350,6 +1445,8 @@ static struct attribute * dasd_attrs[] = {
1350 &dev_attr_erplog.attr, 1445 &dev_attr_erplog.attr,
1351 &dev_attr_failfast.attr, 1446 &dev_attr_failfast.attr,
1352 &dev_attr_expires.attr, 1447 &dev_attr_expires.attr,
1448 &dev_attr_retries.attr,
1449 &dev_attr_timeout.attr,
1353 &dev_attr_reservation_policy.attr, 1450 &dev_attr_reservation_policy.attr,
1354 &dev_attr_last_known_reservation_state.attr, 1451 &dev_attr_last_known_reservation_state.attr,
1355 &dev_attr_safe_offline.attr, 1452 &dev_attr_safe_offline.attr,
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index cc0603358522..feca317b33de 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -359,6 +359,7 @@ dasd_diag_check_device(struct dasd_device *device)
359 } 359 }
360 360
361 device->default_expires = DIAG_TIMEOUT; 361 device->default_expires = DIAG_TIMEOUT;
362 device->default_retries = DIAG_MAX_RETRIES;
362 363
363 /* Figure out position of label block */ 364 /* Figure out position of label block */
364 switch (private->rdc_data.vdev_class) { 365 switch (private->rdc_data.vdev_class) {
@@ -555,7 +556,7 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
555 recid++; 556 recid++;
556 } 557 }
557 } 558 }
558 cqr->retries = DIAG_MAX_RETRIES; 559 cqr->retries = memdev->default_retries;
559 cqr->buildclk = get_tod_clock(); 560 cqr->buildclk = get_tod_clock();
560 if (blk_noretry_request(req) || 561 if (blk_noretry_request(req) ||
561 block->base->features & DASD_FEATURE_FAILFAST) 562 block->base->features & DASD_FEATURE_FAILFAST)
@@ -582,7 +583,10 @@ dasd_diag_free_cp(struct dasd_ccw_req *cqr, struct request *req)
582 583
583static void dasd_diag_handle_terminated_request(struct dasd_ccw_req *cqr) 584static void dasd_diag_handle_terminated_request(struct dasd_ccw_req *cqr)
584{ 585{
585 cqr->status = DASD_CQR_FILLED; 586 if (cqr->retries < 0)
587 cqr->status = DASD_CQR_FAILED;
588 else
589 cqr->status = DASD_CQR_FILLED;
586}; 590};
587 591
588/* Fill in IOCTL data for device. */ 592/* Fill in IOCTL data for device. */
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 6a44b27623ed..e61a6deea3c0 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1682,6 +1682,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1682 1682
1683 /* set default timeout */ 1683 /* set default timeout */
1684 device->default_expires = DASD_EXPIRES; 1684 device->default_expires = DASD_EXPIRES;
1685 /* set default retry count */
1686 device->default_retries = DASD_RETRIES;
1687
1685 if (private->gneq) { 1688 if (private->gneq) {
1686 value = 1; 1689 value = 1;
1687 for (i = 0; i < private->gneq->timeout.value; i++) 1690 for (i = 0; i < private->gneq->timeout.value; i++)
@@ -2378,6 +2381,10 @@ sleep:
2378 2381
2379static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr) 2382static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr)
2380{ 2383{
2384 if (cqr->retries < 0) {
2385 cqr->status = DASD_CQR_FAILED;
2386 return;
2387 }
2381 cqr->status = DASD_CQR_FILLED; 2388 cqr->status = DASD_CQR_FILLED;
2382 if (cqr->block && (cqr->startdev != cqr->block->base)) { 2389 if (cqr->block && (cqr->startdev != cqr->block->base)) {
2383 dasd_eckd_reset_ccw_to_base_io(cqr); 2390 dasd_eckd_reset_ccw_to_base_io(cqr);
@@ -2659,7 +2666,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
2659 cqr->block = block; 2666 cqr->block = block;
2660 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ 2667 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
2661 cqr->lpm = startdev->path_data.ppm; 2668 cqr->lpm = startdev->path_data.ppm;
2662 cqr->retries = 256; 2669 cqr->retries = startdev->default_retries;
2663 cqr->buildclk = get_tod_clock(); 2670 cqr->buildclk = get_tod_clock();
2664 cqr->status = DASD_CQR_FILLED; 2671 cqr->status = DASD_CQR_FILLED;
2665 return cqr; 2672 return cqr;
@@ -2834,7 +2841,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
2834 cqr->block = block; 2841 cqr->block = block;
2835 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ 2842 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
2836 cqr->lpm = startdev->path_data.ppm; 2843 cqr->lpm = startdev->path_data.ppm;
2837 cqr->retries = 256; 2844 cqr->retries = startdev->default_retries;
2838 cqr->buildclk = get_tod_clock(); 2845 cqr->buildclk = get_tod_clock();
2839 cqr->status = DASD_CQR_FILLED; 2846 cqr->status = DASD_CQR_FILLED;
2840 return cqr; 2847 return cqr;
@@ -2968,7 +2975,7 @@ static int prepare_itcw(struct itcw *itcw,
2968 2975
2969 dcw = itcw_add_dcw(itcw, pfx_cmd, 0, 2976 dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
2970 &pfxdata, sizeof(pfxdata), total_data_size); 2977 &pfxdata, sizeof(pfxdata), total_data_size);
2971 return IS_ERR(dcw) ? PTR_ERR(dcw) : 0; 2978 return PTR_RET(dcw);
2972} 2979}
2973 2980
2974static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( 2981static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
@@ -3127,7 +3134,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
3127 cqr->block = block; 3134 cqr->block = block;
3128 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ 3135 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
3129 cqr->lpm = startdev->path_data.ppm; 3136 cqr->lpm = startdev->path_data.ppm;
3130 cqr->retries = 256; 3137 cqr->retries = startdev->default_retries;
3131 cqr->buildclk = get_tod_clock(); 3138 cqr->buildclk = get_tod_clock();
3132 cqr->status = DASD_CQR_FILLED; 3139 cqr->status = DASD_CQR_FILLED;
3133 return cqr; 3140 return cqr;
@@ -3330,7 +3337,7 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
3330 cqr->block = block; 3337 cqr->block = block;
3331 cqr->expires = startdev->default_expires * HZ; 3338 cqr->expires = startdev->default_expires * HZ;
3332 cqr->lpm = startdev->path_data.ppm; 3339 cqr->lpm = startdev->path_data.ppm;
3333 cqr->retries = 256; 3340 cqr->retries = startdev->default_retries;
3334 cqr->buildclk = get_tod_clock(); 3341 cqr->buildclk = get_tod_clock();
3335 cqr->status = DASD_CQR_FILLED; 3342 cqr->status = DASD_CQR_FILLED;
3336 3343
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 3250cb471f78..8d11f773a752 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -159,6 +159,14 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
159 struct dasd_device *device; 159 struct dasd_device *device;
160 160
161 device = cqr->startdev; 161 device = cqr->startdev;
162 if (cqr->intrc == -ETIMEDOUT) {
163 dev_err(&device->cdev->dev, "cqr %p timeout error", cqr);
164 return;
165 }
166 if (cqr->intrc == -ENOLINK) {
167 dev_err(&device->cdev->dev, "cqr %p transport error", cqr);
168 return;
169 }
162 /* dump sense data */ 170 /* dump sense data */
163 if (device->discipline && device->discipline->dump_sense) 171 if (device->discipline && device->discipline->dump_sense)
164 device->discipline->dump_sense(device, cqr, irb); 172 device->discipline->dump_sense(device, cqr, irb);
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 4dd0e2f6047e..9cbc8c32ba59 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -29,6 +29,8 @@
29#endif /* PRINTK_HEADER */ 29#endif /* PRINTK_HEADER */
30#define PRINTK_HEADER "dasd(fba):" 30#define PRINTK_HEADER "dasd(fba):"
31 31
32#define FBA_DEFAULT_RETRIES 32
33
32#define DASD_FBA_CCW_WRITE 0x41 34#define DASD_FBA_CCW_WRITE 0x41
33#define DASD_FBA_CCW_READ 0x42 35#define DASD_FBA_CCW_READ 0x42
34#define DASD_FBA_CCW_LOCATE 0x43 36#define DASD_FBA_CCW_LOCATE 0x43
@@ -167,6 +169,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
167 } 169 }
168 170
169 device->default_expires = DASD_EXPIRES; 171 device->default_expires = DASD_EXPIRES;
172 device->default_retries = FBA_DEFAULT_RETRIES;
170 device->path_data.opm = LPM_ANYPATH; 173 device->path_data.opm = LPM_ANYPATH;
171 174
172 readonly = dasd_device_is_ro(device); 175 readonly = dasd_device_is_ro(device);
@@ -369,7 +372,7 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
369 cqr->memdev = memdev; 372 cqr->memdev = memdev;
370 cqr->block = block; 373 cqr->block = block;
371 cqr->expires = memdev->default_expires * HZ; /* default 5 minutes */ 374 cqr->expires = memdev->default_expires * HZ; /* default 5 minutes */
372 cqr->retries = 32; 375 cqr->retries = memdev->default_retries;
373 cqr->buildclk = get_tod_clock(); 376 cqr->buildclk = get_tod_clock();
374 cqr->status = DASD_CQR_FILLED; 377 cqr->status = DASD_CQR_FILLED;
375 return cqr; 378 return cqr;
@@ -425,7 +428,10 @@ out:
425 428
426static void dasd_fba_handle_terminated_request(struct dasd_ccw_req *cqr) 429static void dasd_fba_handle_terminated_request(struct dasd_ccw_req *cqr)
427{ 430{
428 cqr->status = DASD_CQR_FILLED; 431 if (cqr->retries < 0)
432 cqr->status = DASD_CQR_FAILED;
433 else
434 cqr->status = DASD_CQR_FILLED;
429}; 435};
430 436
431static int 437static int
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 0785bd9bd5b6..690001af0d09 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -224,6 +224,8 @@ struct dasd_ccw_req {
224/* default expiration time*/ 224/* default expiration time*/
225#define DASD_EXPIRES 300 225#define DASD_EXPIRES 300
226#define DASD_EXPIRES_MAX 40000000 226#define DASD_EXPIRES_MAX 40000000
227#define DASD_RETRIES 256
228#define DASD_RETRIES_MAX 32768
227 229
228/* per dasd_ccw_req flags */ 230/* per dasd_ccw_req flags */
229#define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ 231#define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */
@@ -466,6 +468,9 @@ struct dasd_device {
466 468
467 /* default expiration time in s */ 469 /* default expiration time in s */
468 unsigned long default_expires; 470 unsigned long default_expires;
471 unsigned long default_retries;
472
473 unsigned long blk_timeout;
469 474
470 struct dentry *debugfs_dentry; 475 struct dentry *debugfs_dentry;
471 struct dasd_profile profile; 476 struct dasd_profile profile;
@@ -519,7 +524,10 @@ struct dasd_block {
519#define DASD_FLAG_SUSPENDED 9 /* The device was suspended */ 524#define DASD_FLAG_SUSPENDED 9 /* The device was suspended */
520#define DASD_FLAG_SAFE_OFFLINE 10 /* safe offline processing requested*/ 525#define DASD_FLAG_SAFE_OFFLINE 10 /* safe offline processing requested*/
521#define DASD_FLAG_SAFE_OFFLINE_RUNNING 11 /* safe offline running */ 526#define DASD_FLAG_SAFE_OFFLINE_RUNNING 11 /* safe offline running */
527#define DASD_FLAG_ABORTALL 12 /* Abort all noretry requests */
522 528
529#define DASD_SLEEPON_START_TAG ((void *) 1)
530#define DASD_SLEEPON_END_TAG ((void *) 2)
523 531
524void dasd_put_device_wake(struct dasd_device *); 532void dasd_put_device_wake(struct dasd_device *);
525 533
@@ -660,6 +668,8 @@ void dasd_free_device(struct dasd_device *);
660struct dasd_block *dasd_alloc_block(void); 668struct dasd_block *dasd_alloc_block(void);
661void dasd_free_block(struct dasd_block *); 669void dasd_free_block(struct dasd_block *);
662 670
671enum blk_eh_timer_return dasd_times_out(struct request *req);
672
663void dasd_enable_device(struct dasd_device *); 673void dasd_enable_device(struct dasd_device *);
664void dasd_set_target_state(struct dasd_device *, int); 674void dasd_set_target_state(struct dasd_device *, int);
665void dasd_kick_device(struct dasd_device *); 675void dasd_kick_device(struct dasd_device *);
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 8be1b51e9311..25a0f2f8b0b9 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -141,6 +141,59 @@ static int dasd_ioctl_resume(struct dasd_block *block)
141} 141}
142 142
143/* 143/*
144 * Abort all failfast I/O on a device.
145 */
146static int dasd_ioctl_abortio(struct dasd_block *block)
147{
148 unsigned long flags;
149 struct dasd_device *base;
150 struct dasd_ccw_req *cqr, *n;
151
152 base = block->base;
153 if (!capable(CAP_SYS_ADMIN))
154 return -EACCES;
155
156 if (test_and_set_bit(DASD_FLAG_ABORTALL, &base->flags))
157 return 0;
158 DBF_DEV_EVENT(DBF_NOTICE, base, "%s", "abortall flag set");
159
160 spin_lock_irqsave(&block->request_queue_lock, flags);
161 spin_lock(&block->queue_lock);
162 list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) {
163 if (test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
164 cqr->callback_data &&
165 cqr->callback_data != DASD_SLEEPON_START_TAG &&
166 cqr->callback_data != DASD_SLEEPON_END_TAG) {
167 spin_unlock(&block->queue_lock);
168 blk_abort_request(cqr->callback_data);
169 spin_lock(&block->queue_lock);
170 }
171 }
172 spin_unlock(&block->queue_lock);
173 spin_unlock_irqrestore(&block->request_queue_lock, flags);
174
175 dasd_schedule_block_bh(block);
176 return 0;
177}
178
179/*
180 * Allow I/O on a device
181 */
182static int dasd_ioctl_allowio(struct dasd_block *block)
183{
184 struct dasd_device *base;
185
186 base = block->base;
187 if (!capable(CAP_SYS_ADMIN))
188 return -EACCES;
189
190 if (test_and_clear_bit(DASD_FLAG_ABORTALL, &base->flags))
191 DBF_DEV_EVENT(DBF_NOTICE, base, "%s", "abortall flag unset");
192
193 return 0;
194}
195
196/*
144 * performs formatting of _device_ according to _fdata_ 197 * performs formatting of _device_ according to _fdata_
145 * Note: The discipline's format_function is assumed to deliver formatting 198 * Note: The discipline's format_function is assumed to deliver formatting
146 * commands to format multiple units of the device. In terms of the ECKD 199 * commands to format multiple units of the device. In terms of the ECKD
@@ -458,6 +511,12 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode,
458 case BIODASDRESUME: 511 case BIODASDRESUME:
459 rc = dasd_ioctl_resume(block); 512 rc = dasd_ioctl_resume(block);
460 break; 513 break;
514 case BIODASDABORTIO:
515 rc = dasd_ioctl_abortio(block);
516 break;
517 case BIODASDALLOWIO:
518 rc = dasd_ioctl_allowio(block);
519 break;
461 case BIODASDFMT: 520 case BIODASDFMT:
462 rc = dasd_ioctl_format(bdev, argp); 521 rc = dasd_ioctl_format(bdev, argp);
463 break; 522 break;
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index f3c325207445..17821a026c9c 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ 5obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
6 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o 6 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o
7 7
8obj-$(CONFIG_TN3270) += raw3270.o 8obj-$(CONFIG_TN3270) += raw3270.o
9obj-$(CONFIG_TN3270_CONSOLE) += con3270.o 9obj-$(CONFIG_TN3270_CONSOLE) += con3270.o
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index bd6871bf545a..3e4fb4e858da 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -50,11 +50,42 @@ static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
50/* Suspend request */ 50/* Suspend request */
51static DECLARE_COMPLETION(sclp_request_queue_flushed); 51static DECLARE_COMPLETION(sclp_request_queue_flushed);
52 52
53/* Number of console pages to allocate, used by sclp_con.c and sclp_vt220.c */
54int sclp_console_pages = SCLP_CONSOLE_PAGES;
55/* Flag to indicate if buffer pages are dropped on buffer full condition */
56int sclp_console_drop = 0;
57/* Number of times the console dropped buffer pages */
58unsigned long sclp_console_full;
59
53static void sclp_suspend_req_cb(struct sclp_req *req, void *data) 60static void sclp_suspend_req_cb(struct sclp_req *req, void *data)
54{ 61{
55 complete(&sclp_request_queue_flushed); 62 complete(&sclp_request_queue_flushed);
56} 63}
57 64
65static int __init sclp_setup_console_pages(char *str)
66{
67 int pages, rc;
68
69 rc = kstrtoint(str, 0, &pages);
70 if (!rc && pages >= SCLP_CONSOLE_PAGES)
71 sclp_console_pages = pages;
72 return 1;
73}
74
75__setup("sclp_con_pages=", sclp_setup_console_pages);
76
77static int __init sclp_setup_console_drop(char *str)
78{
79 int drop, rc;
80
81 rc = kstrtoint(str, 0, &drop);
82 if (!rc && drop)
83 sclp_console_drop = 1;
84 return 1;
85}
86
87__setup("sclp_con_drop=", sclp_setup_console_drop);
88
58static struct sclp_req sclp_suspend_req; 89static struct sclp_req sclp_suspend_req;
59 90
60/* Timer for request retries. */ 91/* Timer for request retries. */
@@ -117,14 +148,19 @@ static int sclp_init(void);
117int 148int
118sclp_service_call(sclp_cmdw_t command, void *sccb) 149sclp_service_call(sclp_cmdw_t command, void *sccb)
119{ 150{
120 int cc; 151 int cc = 4; /* Initialize for program check handling */
121 152
122 asm volatile( 153 asm volatile(
123 " .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */ 154 "0: .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
124 " ipm %0\n" 155 "1: ipm %0\n"
125 " srl %0,28" 156 " srl %0,28\n"
126 : "=&d" (cc) : "d" (command), "a" (__pa(sccb)) 157 "2:\n"
158 EX_TABLE(0b, 2b)
159 EX_TABLE(1b, 2b)
160 : "+&d" (cc) : "d" (command), "a" (__pa(sccb))
127 : "cc", "memory"); 161 : "cc", "memory");
162 if (cc == 4)
163 return -EINVAL;
128 if (cc == 3) 164 if (cc == 3)
129 return -EIO; 165 return -EIO;
130 if (cc == 2) 166 if (cc == 2)
@@ -1013,11 +1049,47 @@ static const struct dev_pm_ops sclp_pm_ops = {
1013 .restore = sclp_restore, 1049 .restore = sclp_restore,
1014}; 1050};
1015 1051
1052static ssize_t sclp_show_console_pages(struct device_driver *dev, char *buf)
1053{
1054 return sprintf(buf, "%i\n", sclp_console_pages);
1055}
1056
1057static DRIVER_ATTR(con_pages, S_IRUSR, sclp_show_console_pages, NULL);
1058
1059static ssize_t sclp_show_con_drop(struct device_driver *dev, char *buf)
1060{
1061 return sprintf(buf, "%i\n", sclp_console_drop);
1062}
1063
1064static DRIVER_ATTR(con_drop, S_IRUSR, sclp_show_con_drop, NULL);
1065
1066static ssize_t sclp_show_console_full(struct device_driver *dev, char *buf)
1067{
1068 return sprintf(buf, "%lu\n", sclp_console_full);
1069}
1070
1071static DRIVER_ATTR(con_full, S_IRUSR, sclp_show_console_full, NULL);
1072
1073static struct attribute *sclp_drv_attrs[] = {
1074 &driver_attr_con_pages.attr,
1075 &driver_attr_con_drop.attr,
1076 &driver_attr_con_full.attr,
1077 NULL,
1078};
1079static struct attribute_group sclp_drv_attr_group = {
1080 .attrs = sclp_drv_attrs,
1081};
1082static const struct attribute_group *sclp_drv_attr_groups[] = {
1083 &sclp_drv_attr_group,
1084 NULL,
1085};
1086
1016static struct platform_driver sclp_pdrv = { 1087static struct platform_driver sclp_pdrv = {
1017 .driver = { 1088 .driver = {
1018 .name = "sclp", 1089 .name = "sclp",
1019 .owner = THIS_MODULE, 1090 .owner = THIS_MODULE,
1020 .pm = &sclp_pm_ops, 1091 .pm = &sclp_pm_ops,
1092 .groups = sclp_drv_attr_groups,
1021 }, 1093 },
1022}; 1094};
1023 1095
@@ -1096,10 +1168,12 @@ static __init int sclp_initcall(void)
1096 rc = platform_driver_register(&sclp_pdrv); 1168 rc = platform_driver_register(&sclp_pdrv);
1097 if (rc) 1169 if (rc)
1098 return rc; 1170 return rc;
1171
1099 sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0); 1172 sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
1100 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0; 1173 rc = PTR_RET(sclp_pdev);
1101 if (rc) 1174 if (rc)
1102 goto fail_platform_driver_unregister; 1175 goto fail_platform_driver_unregister;
1176
1103 rc = atomic_notifier_chain_register(&panic_notifier_list, 1177 rc = atomic_notifier_chain_register(&panic_notifier_list,
1104 &sclp_on_panic_nb); 1178 &sclp_on_panic_nb);
1105 if (rc) 1179 if (rc)
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index 25bcd4c0ed82..40d1406289ed 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -15,7 +15,7 @@
15 15
16/* maximum number of pages concerning our own memory management */ 16/* maximum number of pages concerning our own memory management */
17#define MAX_KMEM_PAGES (sizeof(unsigned long) << 3) 17#define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
18#define MAX_CONSOLE_PAGES 6 18#define SCLP_CONSOLE_PAGES 6
19 19
20#define EVTYP_OPCMD 0x01 20#define EVTYP_OPCMD 0x01
21#define EVTYP_MSG 0x02 21#define EVTYP_MSG 0x02
@@ -171,10 +171,15 @@ int sclp_remove_processed(struct sccb_header *sccb);
171int sclp_deactivate(void); 171int sclp_deactivate(void);
172int sclp_reactivate(void); 172int sclp_reactivate(void);
173int sclp_service_call(sclp_cmdw_t command, void *sccb); 173int sclp_service_call(sclp_cmdw_t command, void *sccb);
174int sclp_sync_request(sclp_cmdw_t command, void *sccb);
174 175
175int sclp_sdias_init(void); 176int sclp_sdias_init(void);
176void sclp_sdias_exit(void); 177void sclp_sdias_exit(void);
177 178
179extern int sclp_console_pages;
180extern int sclp_console_drop;
181extern unsigned long sclp_console_full;
182
178/* useful inlines */ 183/* useful inlines */
179 184
180/* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */ 185/* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index bf07c3a188d4..8cd34bf644b3 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -195,7 +195,7 @@ static void sclp_sync_callback(struct sclp_req *req, void *data)
195 complete(completion); 195 complete(completion);
196} 196}
197 197
198static int do_sync_request(sclp_cmdw_t cmd, void *sccb) 198int sclp_sync_request(sclp_cmdw_t cmd, void *sccb)
199{ 199{
200 struct completion completion; 200 struct completion completion;
201 struct sclp_req *request; 201 struct sclp_req *request;
@@ -270,7 +270,7 @@ int sclp_get_cpu_info(struct sclp_cpu_info *info)
270 if (!sccb) 270 if (!sccb)
271 return -ENOMEM; 271 return -ENOMEM;
272 sccb->header.length = sizeof(*sccb); 272 sccb->header.length = sizeof(*sccb);
273 rc = do_sync_request(SCLP_CMDW_READ_CPU_INFO, sccb); 273 rc = sclp_sync_request(SCLP_CMDW_READ_CPU_INFO, sccb);
274 if (rc) 274 if (rc)
275 goto out; 275 goto out;
276 if (sccb->header.response_code != 0x0010) { 276 if (sccb->header.response_code != 0x0010) {
@@ -304,7 +304,7 @@ static int do_cpu_configure(sclp_cmdw_t cmd)
304 if (!sccb) 304 if (!sccb)
305 return -ENOMEM; 305 return -ENOMEM;
306 sccb->header.length = sizeof(*sccb); 306 sccb->header.length = sizeof(*sccb);
307 rc = do_sync_request(cmd, sccb); 307 rc = sclp_sync_request(cmd, sccb);
308 if (rc) 308 if (rc)
309 goto out; 309 goto out;
310 switch (sccb->header.response_code) { 310 switch (sccb->header.response_code) {
@@ -374,7 +374,7 @@ static int do_assign_storage(sclp_cmdw_t cmd, u16 rn)
374 return -ENOMEM; 374 return -ENOMEM;
375 sccb->header.length = PAGE_SIZE; 375 sccb->header.length = PAGE_SIZE;
376 sccb->rn = rn; 376 sccb->rn = rn;
377 rc = do_sync_request(cmd, sccb); 377 rc = sclp_sync_request(cmd, sccb);
378 if (rc) 378 if (rc)
379 goto out; 379 goto out;
380 switch (sccb->header.response_code) { 380 switch (sccb->header.response_code) {
@@ -429,7 +429,7 @@ static int sclp_attach_storage(u8 id)
429 if (!sccb) 429 if (!sccb)
430 return -ENOMEM; 430 return -ENOMEM;
431 sccb->header.length = PAGE_SIZE; 431 sccb->header.length = PAGE_SIZE;
432 rc = do_sync_request(0x00080001 | id << 8, sccb); 432 rc = sclp_sync_request(0x00080001 | id << 8, sccb);
433 if (rc) 433 if (rc)
434 goto out; 434 goto out;
435 switch (sccb->header.response_code) { 435 switch (sccb->header.response_code) {
@@ -627,7 +627,7 @@ static int __init sclp_detect_standby_memory(void)
627 for (id = 0; id <= sclp_max_storage_id; id++) { 627 for (id = 0; id <= sclp_max_storage_id; id++) {
628 memset(sccb, 0, PAGE_SIZE); 628 memset(sccb, 0, PAGE_SIZE);
629 sccb->header.length = PAGE_SIZE; 629 sccb->header.length = PAGE_SIZE;
630 rc = do_sync_request(0x00040001 | id << 8, sccb); 630 rc = sclp_sync_request(0x00040001 | id << 8, sccb);
631 if (rc) 631 if (rc)
632 goto out; 632 goto out;
633 switch (sccb->header.response_code) { 633 switch (sccb->header.response_code) {
@@ -668,7 +668,7 @@ static int __init sclp_detect_standby_memory(void)
668 if (rc) 668 if (rc)
669 goto out; 669 goto out;
670 sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0); 670 sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0);
671 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0; 671 rc = PTR_RET(sclp_pdev);
672 if (rc) 672 if (rc)
673 goto out_driver; 673 goto out_driver;
674 sclp_add_standby_memory(); 674 sclp_add_standby_memory();
@@ -714,7 +714,7 @@ static int do_pci_configure(sclp_cmdw_t cmd, u32 fid)
714 sccb->header.length = PAGE_SIZE; 714 sccb->header.length = PAGE_SIZE;
715 sccb->atype = SCLP_RECONFIG_PCI_ATPYE; 715 sccb->atype = SCLP_RECONFIG_PCI_ATPYE;
716 sccb->aid = fid; 716 sccb->aid = fid;
717 rc = do_sync_request(cmd, sccb); 717 rc = sclp_sync_request(cmd, sccb);
718 if (rc) 718 if (rc)
719 goto out; 719 goto out;
720 switch (sccb->header.response_code) { 720 switch (sccb->header.response_code) {
@@ -771,7 +771,7 @@ static int do_chp_configure(sclp_cmdw_t cmd)
771 if (!sccb) 771 if (!sccb)
772 return -ENOMEM; 772 return -ENOMEM;
773 sccb->header.length = sizeof(*sccb); 773 sccb->header.length = sizeof(*sccb);
774 rc = do_sync_request(cmd, sccb); 774 rc = sclp_sync_request(cmd, sccb);
775 if (rc) 775 if (rc)
776 goto out; 776 goto out;
777 switch (sccb->header.response_code) { 777 switch (sccb->header.response_code) {
@@ -846,7 +846,7 @@ int sclp_chp_read_info(struct sclp_chp_info *info)
846 if (!sccb) 846 if (!sccb)
847 return -ENOMEM; 847 return -ENOMEM;
848 sccb->header.length = sizeof(*sccb); 848 sccb->header.length = sizeof(*sccb);
849 rc = do_sync_request(SCLP_CMDW_READ_CHPATH_INFORMATION, sccb); 849 rc = sclp_sync_request(SCLP_CMDW_READ_CHPATH_INFORMATION, sccb);
850 if (rc) 850 if (rc)
851 goto out; 851 goto out;
852 if (sccb->header.response_code != 0x0010) { 852 if (sccb->header.response_code != 0x0010) {
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
index ecf45c54f8c4..5880def98fc1 100644
--- a/drivers/s390/char/sclp_con.c
+++ b/drivers/s390/char/sclp_con.c
@@ -130,6 +130,31 @@ sclp_console_timeout(unsigned long data)
130} 130}
131 131
132/* 132/*
133 * Drop oldest console buffer if sclp_con_drop is set
134 */
135static int
136sclp_console_drop_buffer(void)
137{
138 struct list_head *list;
139 struct sclp_buffer *buffer;
140 void *page;
141
142 if (!sclp_console_drop)
143 return 0;
144 list = sclp_con_outqueue.next;
145 if (sclp_con_queue_running)
146 /* The first element is in I/O */
147 list = list->next;
148 if (list == &sclp_con_outqueue)
149 return 0;
150 list_del(list);
151 buffer = list_entry(list, struct sclp_buffer, list);
152 page = sclp_unmake_buffer(buffer);
153 list_add_tail((struct list_head *) page, &sclp_con_pages);
154 return 1;
155}
156
157/*
133 * Writes the given message to S390 system console 158 * Writes the given message to S390 system console
134 */ 159 */
135static void 160static void
@@ -150,9 +175,13 @@ sclp_console_write(struct console *console, const char *message,
150 do { 175 do {
151 /* make sure we have a console output buffer */ 176 /* make sure we have a console output buffer */
152 if (sclp_conbuf == NULL) { 177 if (sclp_conbuf == NULL) {
178 if (list_empty(&sclp_con_pages))
179 sclp_console_full++;
153 while (list_empty(&sclp_con_pages)) { 180 while (list_empty(&sclp_con_pages)) {
154 if (sclp_con_suspended) 181 if (sclp_con_suspended)
155 goto out; 182 goto out;
183 if (sclp_console_drop_buffer())
184 break;
156 spin_unlock_irqrestore(&sclp_con_lock, flags); 185 spin_unlock_irqrestore(&sclp_con_lock, flags);
157 sclp_sync_wait(); 186 sclp_sync_wait();
158 spin_lock_irqsave(&sclp_con_lock, flags); 187 spin_lock_irqsave(&sclp_con_lock, flags);
@@ -297,7 +326,7 @@ sclp_console_init(void)
297 return rc; 326 return rc;
298 /* Allocate pages for output buffering */ 327 /* Allocate pages for output buffering */
299 INIT_LIST_HEAD(&sclp_con_pages); 328 INIT_LIST_HEAD(&sclp_con_pages);
300 for (i = 0; i < MAX_CONSOLE_PAGES; i++) { 329 for (i = 0; i < sclp_console_pages; i++) {
301 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 330 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
302 list_add_tail(page, &sclp_con_pages); 331 list_add_tail(page, &sclp_con_pages);
303 } 332 }
diff --git a/drivers/s390/char/sclp_ctl.c b/drivers/s390/char/sclp_ctl.c
new file mode 100644
index 000000000000..648cb86afd42
--- /dev/null
+++ b/drivers/s390/char/sclp_ctl.c
@@ -0,0 +1,144 @@
1/*
2 * IOCTL interface for SCLP
3 *
4 * Copyright IBM Corp. 2012
5 *
6 * Author: Michael Holzheu <holzheu@linux.vnet.ibm.com>
7 */
8
9#include <linux/compat.h>
10#include <linux/uaccess.h>
11#include <linux/miscdevice.h>
12#include <linux/gfp.h>
13#include <linux/module.h>
14#include <linux/ioctl.h>
15#include <linux/fs.h>
16#include <asm/compat.h>
17#include <asm/sclp_ctl.h>
18#include <asm/sclp.h>
19
20#include "sclp.h"
21
22/*
23 * Supported command words
24 */
25static unsigned int sclp_ctl_sccb_wlist[] = {
26 0x00400002,
27 0x00410002,
28};
29
30/*
31 * Check if command word is supported
32 */
33static int sclp_ctl_cmdw_supported(unsigned int cmdw)
34{
35 int i;
36
37 for (i = 0; i < ARRAY_SIZE(sclp_ctl_sccb_wlist); i++) {
38 if (cmdw == sclp_ctl_sccb_wlist[i])
39 return 1;
40 }
41 return 0;
42}
43
44static void __user *u64_to_uptr(u64 value)
45{
46 if (is_compat_task())
47 return compat_ptr(value);
48 else
49 return (void __user *)(unsigned long)value;
50}
51
52/*
53 * Start SCLP request
54 */
55static int sclp_ctl_ioctl_sccb(void __user *user_area)
56{
57 struct sclp_ctl_sccb ctl_sccb;
58 struct sccb_header *sccb;
59 int rc;
60
61 if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb)))
62 return -EFAULT;
63 if (!sclp_ctl_cmdw_supported(ctl_sccb.cmdw))
64 return -EOPNOTSUPP;
65 sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
66 if (!sccb)
67 return -ENOMEM;
68 if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sizeof(*sccb))) {
69 rc = -EFAULT;
70 goto out_free;
71 }
72 if (sccb->length > PAGE_SIZE || sccb->length < 8)
73 return -EINVAL;
74 if (copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), sccb->length)) {
75 rc = -EFAULT;
76 goto out_free;
77 }
78 rc = sclp_sync_request(ctl_sccb.cmdw, sccb);
79 if (rc)
80 goto out_free;
81 if (copy_to_user(u64_to_uptr(ctl_sccb.sccb), sccb, sccb->length))
82 rc = -EFAULT;
83out_free:
84 free_page((unsigned long) sccb);
85 return rc;
86}
87
88/*
89 * SCLP SCCB ioctl function
90 */
91static long sclp_ctl_ioctl(struct file *filp, unsigned int cmd,
92 unsigned long arg)
93{
94 void __user *argp;
95
96 if (is_compat_task())
97 argp = compat_ptr(arg);
98 else
99 argp = (void __user *) arg;
100 switch (cmd) {
101 case SCLP_CTL_SCCB:
102 return sclp_ctl_ioctl_sccb(argp);
103 default: /* unknown ioctl number */
104 return -ENOTTY;
105 }
106}
107
108/*
109 * File operations
110 */
111static const struct file_operations sclp_ctl_fops = {
112 .owner = THIS_MODULE,
113 .open = nonseekable_open,
114 .unlocked_ioctl = sclp_ctl_ioctl,
115 .compat_ioctl = sclp_ctl_ioctl,
116 .llseek = no_llseek,
117};
118
119/*
120 * Misc device definition
121 */
122static struct miscdevice sclp_ctl_device = {
123 .minor = MISC_DYNAMIC_MINOR,
124 .name = "sclp",
125 .fops = &sclp_ctl_fops,
126};
127
128/*
129 * Register sclp_ctl misc device
130 */
131static int __init sclp_ctl_init(void)
132{
133 return misc_register(&sclp_ctl_device);
134}
135module_init(sclp_ctl_init);
136
137/*
138 * Deregister sclp_ctl misc device
139 */
140static void __exit sclp_ctl_exit(void)
141{
142 misc_deregister(&sclp_ctl_device);
143}
144module_exit(sclp_ctl_exit);
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 5aaaa2ec8df4..4eed38cd0af6 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -362,6 +362,31 @@ sclp_vt220_timeout(unsigned long data)
362 362
363#define BUFFER_MAX_DELAY HZ/20 363#define BUFFER_MAX_DELAY HZ/20
364 364
365/*
366 * Drop oldest console buffer if sclp_con_drop is set
367 */
368static int
369sclp_vt220_drop_buffer(void)
370{
371 struct list_head *list;
372 struct sclp_vt220_request *request;
373 void *page;
374
375 if (!sclp_console_drop)
376 return 0;
377 list = sclp_vt220_outqueue.next;
378 if (sclp_vt220_queue_running)
379 /* The first element is in I/O */
380 list = list->next;
381 if (list == &sclp_vt220_outqueue)
382 return 0;
383 list_del(list);
384 request = list_entry(list, struct sclp_vt220_request, list);
385 page = request->sclp_req.sccb;
386 list_add_tail((struct list_head *) page, &sclp_vt220_empty);
387 return 1;
388}
389
365/* 390/*
366 * Internal implementation of the write function. Write COUNT bytes of data 391 * Internal implementation of the write function. Write COUNT bytes of data
367 * from memory at BUF 392 * from memory at BUF
@@ -390,12 +415,16 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule,
390 do { 415 do {
391 /* Create an sclp output buffer if none exists yet */ 416 /* Create an sclp output buffer if none exists yet */
392 if (sclp_vt220_current_request == NULL) { 417 if (sclp_vt220_current_request == NULL) {
418 if (list_empty(&sclp_vt220_empty))
419 sclp_console_full++;
393 while (list_empty(&sclp_vt220_empty)) { 420 while (list_empty(&sclp_vt220_empty)) {
394 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
395 if (may_fail || sclp_vt220_suspended) 421 if (may_fail || sclp_vt220_suspended)
396 goto out; 422 goto out;
397 else 423 if (sclp_vt220_drop_buffer())
398 sclp_sync_wait(); 424 break;
425 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
426
427 sclp_sync_wait();
399 spin_lock_irqsave(&sclp_vt220_lock, flags); 428 spin_lock_irqsave(&sclp_vt220_lock, flags);
400 } 429 }
401 page = (void *) sclp_vt220_empty.next; 430 page = (void *) sclp_vt220_empty.next;
@@ -428,8 +457,8 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule,
428 sclp_vt220_timer.expires = jiffies + BUFFER_MAX_DELAY; 457 sclp_vt220_timer.expires = jiffies + BUFFER_MAX_DELAY;
429 add_timer(&sclp_vt220_timer); 458 add_timer(&sclp_vt220_timer);
430 } 459 }
431 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
432out: 460out:
461 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
433 return overall_written; 462 return overall_written;
434} 463}
435 464
@@ -803,7 +832,7 @@ sclp_vt220_con_init(void)
803 832
804 if (!CONSOLE_IS_SCLP) 833 if (!CONSOLE_IS_SCLP)
805 return 0; 834 return 0;
806 rc = __sclp_vt220_init(MAX_CONSOLE_PAGES); 835 rc = __sclp_vt220_init(sclp_console_pages);
807 if (rc) 836 if (rc)
808 return rc; 837 return rc;
809 /* Attach linux console */ 838 /* Attach linux console */
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index 54b3c79203f5..91c3c642c76e 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -77,7 +77,7 @@ struct tape_class_device *register_tape_dev(
77 tcd->class_device = device_create(tape_class, device, 77 tcd->class_device = device_create(tape_class, device,
78 tcd->char_device->dev, NULL, 78 tcd->char_device->dev, NULL,
79 "%s", tcd->device_name); 79 "%s", tcd->device_name);
80 rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0; 80 rc = PTR_RET(tcd->class_device);
81 if (rc) 81 if (rc)
82 goto fail_with_cdev; 82 goto fail_with_cdev;
83 rc = sysfs_create_link( 83 rc = sysfs_create_link(
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index e9b72311e254..d5eac985976b 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -112,7 +112,8 @@ static int vmwdt_keepalive(void)
112 112
113static int vmwdt_disable(void) 113static int vmwdt_disable(void)
114{ 114{
115 int ret = __diag288(wdt_cancel, 0, "", 0); 115 char cmd[] = {'\0'};
116 int ret = __diag288(wdt_cancel, 0, cmd, 0);
116 WARN_ON(ret != 0); 117 WARN_ON(ret != 0);
117 clear_bit(VMWDT_RUNNING, &vmwdt_is_open); 118 clear_bit(VMWDT_RUNNING, &vmwdt_is_open);
118 return ret; 119 return ret;
@@ -124,7 +125,7 @@ static int __init vmwdt_probe(void)
124 * so we try initializing it with a NOP command ("BEGIN") 125 * so we try initializing it with a NOP command ("BEGIN")
125 * that won't cause any harm even if the following disable 126 * that won't cause any harm even if the following disable
126 * fails for some reason */ 127 * fails for some reason */
127 static char __initdata ebc_begin[] = { 128 char ebc_begin[] = {
128 194, 197, 199, 201, 213 129 194, 197, 199, 201, 213
129 }; 130 };
130 if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0) 131 if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0)
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index bc10220f6847..91edbd7ee806 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -9,142 +9,87 @@
9 */ 9 */
10 10
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/irq.h>
13#include <linux/kernel_stat.h>
12#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/mutex.h>
16#include <linux/rculist.h>
13#include <linux/slab.h> 17#include <linux/slab.h>
14#include <linux/rcupdate.h>
15 18
16#include <asm/airq.h> 19#include <asm/airq.h>
17#include <asm/isc.h> 20#include <asm/isc.h>
18 21
19#include "cio.h" 22#include "cio.h"
20#include "cio_debug.h" 23#include "cio_debug.h"
24#include "ioasm.h"
21 25
22#define NR_AIRQS 32 26static DEFINE_SPINLOCK(airq_lists_lock);
23#define NR_AIRQS_PER_WORD sizeof(unsigned long) 27static struct hlist_head airq_lists[MAX_ISC+1];
24#define NR_AIRQ_WORDS (NR_AIRQS / NR_AIRQS_PER_WORD)
25
26union indicator_t {
27 unsigned long word[NR_AIRQ_WORDS];
28 unsigned char byte[NR_AIRQS];
29} __attribute__((packed));
30
31struct airq_t {
32 adapter_int_handler_t handler;
33 void *drv_data;
34};
35
36static union indicator_t indicators[MAX_ISC+1];
37static struct airq_t *airqs[MAX_ISC+1][NR_AIRQS];
38
39static int register_airq(struct airq_t *airq, u8 isc)
40{
41 int i;
42
43 for (i = 0; i < NR_AIRQS; i++)
44 if (!cmpxchg(&airqs[isc][i], NULL, airq))
45 return i;
46 return -ENOMEM;
47}
48 28
49/** 29/**
50 * s390_register_adapter_interrupt() - register adapter interrupt handler 30 * register_adapter_interrupt() - register adapter interrupt handler
51 * @handler: adapter handler to be registered 31 * @airq: pointer to adapter interrupt descriptor
52 * @drv_data: driver data passed with each call to the handler
53 * @isc: isc for which the handler should be called
54 * 32 *
55 * Returns: 33 * Returns 0 on success, or -EINVAL.
56 * Pointer to the indicator to be used on success
57 * ERR_PTR() if registration failed
58 */ 34 */
59void *s390_register_adapter_interrupt(adapter_int_handler_t handler, 35int register_adapter_interrupt(struct airq_struct *airq)
60 void *drv_data, u8 isc)
61{ 36{
62 struct airq_t *airq; 37 char dbf_txt[32];
63 char dbf_txt[16]; 38
64 int ret; 39 if (!airq->handler || airq->isc > MAX_ISC)
65 40 return -EINVAL;
66 if (isc > MAX_ISC) 41 if (!airq->lsi_ptr) {
67 return ERR_PTR(-EINVAL); 42 airq->lsi_ptr = kzalloc(1, GFP_KERNEL);
68 airq = kmalloc(sizeof(struct airq_t), GFP_KERNEL); 43 if (!airq->lsi_ptr)
69 if (!airq) { 44 return -ENOMEM;
70 ret = -ENOMEM; 45 airq->flags |= AIRQ_PTR_ALLOCATED;
71 goto out;
72 } 46 }
73 airq->handler = handler; 47 if (!airq->lsi_mask)
74 airq->drv_data = drv_data; 48 airq->lsi_mask = 0xff;
75 49 snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%p", airq);
76 ret = register_airq(airq, isc);
77out:
78 snprintf(dbf_txt, sizeof(dbf_txt), "rairq:%d", ret);
79 CIO_TRACE_EVENT(4, dbf_txt); 50 CIO_TRACE_EVENT(4, dbf_txt);
80 if (ret < 0) { 51 isc_register(airq->isc);
81 kfree(airq); 52 spin_lock(&airq_lists_lock);
82 return ERR_PTR(ret); 53 hlist_add_head_rcu(&airq->list, &airq_lists[airq->isc]);
83 } else 54 spin_unlock(&airq_lists_lock);
84 return &indicators[isc].byte[ret]; 55 return 0;
85} 56}
86EXPORT_SYMBOL(s390_register_adapter_interrupt); 57EXPORT_SYMBOL(register_adapter_interrupt);
87 58
88/** 59/**
89 * s390_unregister_adapter_interrupt - unregister adapter interrupt handler 60 * unregister_adapter_interrupt - unregister adapter interrupt handler
90 * @ind: indicator for which the handler is to be unregistered 61 * @airq: pointer to adapter interrupt descriptor
91 * @isc: interruption subclass
92 */ 62 */
93void s390_unregister_adapter_interrupt(void *ind, u8 isc) 63void unregister_adapter_interrupt(struct airq_struct *airq)
94{ 64{
95 struct airq_t *airq; 65 char dbf_txt[32];
96 char dbf_txt[16];
97 int i;
98 66
99 i = (int) ((addr_t) ind) - ((addr_t) &indicators[isc].byte[0]); 67 if (hlist_unhashed(&airq->list))
100 snprintf(dbf_txt, sizeof(dbf_txt), "urairq:%d", i); 68 return;
69 snprintf(dbf_txt, sizeof(dbf_txt), "urairq:%p", airq);
101 CIO_TRACE_EVENT(4, dbf_txt); 70 CIO_TRACE_EVENT(4, dbf_txt);
102 indicators[isc].byte[i] = 0; 71 spin_lock(&airq_lists_lock);
103 airq = xchg(&airqs[isc][i], NULL); 72 hlist_del_rcu(&airq->list);
104 /* 73 spin_unlock(&airq_lists_lock);
105 * Allow interrupts to complete. This will ensure that the airq handle 74 synchronize_rcu();
106 * is no longer referenced by any interrupt handler. 75 isc_unregister(airq->isc);
107 */ 76 if (airq->flags & AIRQ_PTR_ALLOCATED) {
108 synchronize_sched(); 77 kfree(airq->lsi_ptr);
109 kfree(airq); 78 airq->lsi_ptr = NULL;
79 airq->flags &= ~AIRQ_PTR_ALLOCATED;
80 }
110} 81}
111EXPORT_SYMBOL(s390_unregister_adapter_interrupt); 82EXPORT_SYMBOL(unregister_adapter_interrupt);
112
113#define INDICATOR_MASK (0xffUL << ((NR_AIRQS_PER_WORD - 1) * 8))
114 83
115void do_adapter_IO(u8 isc) 84void do_adapter_IO(u8 isc)
116{ 85{
117 int w; 86 struct airq_struct *airq;
118 int i; 87 struct hlist_head *head;
119 unsigned long word; 88
120 struct airq_t *airq; 89 head = &airq_lists[isc];
121 90 rcu_read_lock();
122 /* 91 hlist_for_each_entry_rcu(airq, head, list)
123 * Access indicator array in word-sized chunks to minimize storage 92 if ((*airq->lsi_ptr & airq->lsi_mask) != 0)
124 * fetch operations. 93 airq->handler(airq);
125 */ 94 rcu_read_unlock();
126 for (w = 0; w < NR_AIRQ_WORDS; w++) {
127 word = indicators[isc].word[w];
128 i = w * NR_AIRQS_PER_WORD;
129 /*
130 * Check bytes within word for active indicators.
131 */
132 while (word) {
133 if (word & INDICATOR_MASK) {
134 airq = airqs[isc][i];
135 /* Make sure gcc reads from airqs only once. */
136 barrier();
137 if (likely(airq))
138 airq->handler(&indicators[isc].byte[i],
139 airq->drv_data);
140 else
141 /*
142 * Reset ill-behaved indicator.
143 */
144 indicators[isc].byte[i] = 0;
145 }
146 word <<= 8;
147 i++;
148 }
149 }
150} 95}
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 8ea7d9b2c671..13299f902676 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -20,6 +20,7 @@
20#include <asm/chpid.h> 20#include <asm/chpid.h>
21#include <asm/chsc.h> 21#include <asm/chsc.h>
22#include <asm/crw.h> 22#include <asm/crw.h>
23#include <asm/isc.h>
23 24
24#include "css.h" 25#include "css.h"
25#include "cio.h" 26#include "cio.h"
@@ -144,6 +145,65 @@ out:
144 return ret; 145 return ret;
145} 146}
146 147
148/**
149 * chsc_ssqd() - store subchannel QDIO data (SSQD)
150 * @schid: id of the subchannel on which SSQD is performed
151 * @ssqd: request and response block for SSQD
152 *
153 * Returns 0 on success.
154 */
155int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd)
156{
157 memset(ssqd, 0, sizeof(*ssqd));
158 ssqd->request.length = 0x0010;
159 ssqd->request.code = 0x0024;
160 ssqd->first_sch = schid.sch_no;
161 ssqd->last_sch = schid.sch_no;
162 ssqd->ssid = schid.ssid;
163
164 if (chsc(ssqd))
165 return -EIO;
166
167 return chsc_error_from_response(ssqd->response.code);
168}
169EXPORT_SYMBOL_GPL(chsc_ssqd);
170
171/**
172 * chsc_sadc() - set adapter device controls (SADC)
173 * @schid: id of the subchannel on which SADC is performed
174 * @scssc: request and response block for SADC
175 * @summary_indicator_addr: summary indicator address
176 * @subchannel_indicator_addr: subchannel indicator address
177 *
178 * Returns 0 on success.
179 */
180int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc,
181 u64 summary_indicator_addr, u64 subchannel_indicator_addr)
182{
183 memset(scssc, 0, sizeof(*scssc));
184 scssc->request.length = 0x0fe0;
185 scssc->request.code = 0x0021;
186 scssc->operation_code = 0;
187
188 scssc->summary_indicator_addr = summary_indicator_addr;
189 scssc->subchannel_indicator_addr = subchannel_indicator_addr;
190
191 scssc->ks = PAGE_DEFAULT_KEY >> 4;
192 scssc->kc = PAGE_DEFAULT_KEY >> 4;
193 scssc->isc = QDIO_AIRQ_ISC;
194 scssc->schid = schid;
195
196 /* enable the time delay disablement facility */
197 if (css_general_characteristics.aif_tdd)
198 scssc->word_with_d_bit = 0x10000000;
199
200 if (chsc(scssc))
201 return -EIO;
202
203 return chsc_error_from_response(scssc->response.code);
204}
205EXPORT_SYMBOL_GPL(chsc_sadc);
206
147static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) 207static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data)
148{ 208{
149 spin_lock_irq(sch->lock); 209 spin_lock_irq(sch->lock);
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index e7ef2a683b8f..23d072e70eb2 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -7,14 +7,10 @@
7#include <asm/chpid.h> 7#include <asm/chpid.h>
8#include <asm/chsc.h> 8#include <asm/chsc.h>
9#include <asm/schid.h> 9#include <asm/schid.h>
10#include <asm/qdio.h>
10 11
11#define CHSC_SDA_OC_MSS 0x2 12#define CHSC_SDA_OC_MSS 0x2
12 13
13struct chsc_header {
14 u16 length;
15 u16 code;
16} __attribute__ ((packed));
17
18#define NR_MEASUREMENT_CHARS 5 14#define NR_MEASUREMENT_CHARS 5
19struct cmg_chars { 15struct cmg_chars {
20 u32 values[NR_MEASUREMENT_CHARS]; 16 u32 values[NR_MEASUREMENT_CHARS];
@@ -77,6 +73,40 @@ struct chsc_ssd_info {
77 u16 fla[8]; 73 u16 fla[8];
78}; 74};
79 75
76struct chsc_ssqd_area {
77 struct chsc_header request;
78 u16:10;
79 u8 ssid:2;
80 u8 fmt:4;
81 u16 first_sch;
82 u16:16;
83 u16 last_sch;
84 u32:32;
85 struct chsc_header response;
86 u32:32;
87 struct qdio_ssqd_desc qdio_ssqd;
88} __packed;
89
90struct chsc_scssc_area {
91 struct chsc_header request;
92 u16 operation_code;
93 u16:16;
94 u32:32;
95 u32:32;
96 u64 summary_indicator_addr;
97 u64 subchannel_indicator_addr;
98 u32 ks:4;
99 u32 kc:4;
100 u32:21;
101 u32 isc:3;
102 u32 word_with_d_bit;
103 u32:32;
104 struct subchannel_id schid;
105 u32 reserved[1004];
106 struct chsc_header response;
107 u32:32;
108} __packed;
109
80struct chsc_scpd { 110struct chsc_scpd {
81 struct chsc_header request; 111 struct chsc_header request;
82 u32:2; 112 u32:2;
@@ -116,7 +146,9 @@ int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid,
116void chsc_chp_online(struct chp_id chpid); 146void chsc_chp_online(struct chp_id chpid);
117void chsc_chp_offline(struct chp_id chpid); 147void chsc_chp_offline(struct chp_id chpid);
118int chsc_get_channel_measurement_chars(struct channel_path *chp); 148int chsc_get_channel_measurement_chars(struct channel_path *chp);
119 149int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd);
150int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc,
151 u64 summary_indicator_addr, u64 subchannel_indicator_addr);
120int chsc_error_from_response(int response); 152int chsc_error_from_response(int response);
121 153
122int chsc_siosl(struct subchannel_id schid); 154int chsc_siosl(struct subchannel_id schid);
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index facdf809113f..7b29d0be0ca3 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -29,6 +29,10 @@
29static debug_info_t *chsc_debug_msg_id; 29static debug_info_t *chsc_debug_msg_id;
30static debug_info_t *chsc_debug_log_id; 30static debug_info_t *chsc_debug_log_id;
31 31
32static struct chsc_request *on_close_request;
33static struct chsc_async_area *on_close_chsc_area;
34static DEFINE_MUTEX(on_close_mutex);
35
32#define CHSC_MSG(imp, args...) do { \ 36#define CHSC_MSG(imp, args...) do { \
33 debug_sprintf_event(chsc_debug_msg_id, imp , ##args); \ 37 debug_sprintf_event(chsc_debug_msg_id, imp , ##args); \
34 } while (0) 38 } while (0)
@@ -258,7 +262,7 @@ static int chsc_async(struct chsc_async_area *chsc_area,
258 CHSC_LOG(2, "schid"); 262 CHSC_LOG(2, "schid");
259 CHSC_LOG_HEX(2, &sch->schid, sizeof(sch->schid)); 263 CHSC_LOG_HEX(2, &sch->schid, sizeof(sch->schid));
260 cc = chsc(chsc_area); 264 cc = chsc(chsc_area);
261 sprintf(dbf, "cc:%d", cc); 265 snprintf(dbf, sizeof(dbf), "cc:%d", cc);
262 CHSC_LOG(2, dbf); 266 CHSC_LOG(2, dbf);
263 switch (cc) { 267 switch (cc) {
264 case 0: 268 case 0:
@@ -287,11 +291,11 @@ static int chsc_async(struct chsc_async_area *chsc_area,
287 return ret; 291 return ret;
288} 292}
289 293
290static void chsc_log_command(struct chsc_async_area *chsc_area) 294static void chsc_log_command(void *chsc_area)
291{ 295{
292 char dbf[10]; 296 char dbf[10];
293 297
294 sprintf(dbf, "CHSC:%x", chsc_area->header.code); 298 snprintf(dbf, sizeof(dbf), "CHSC:%x", ((uint16_t *)chsc_area)[1]);
295 CHSC_LOG(0, dbf); 299 CHSC_LOG(0, dbf);
296 CHSC_LOG_HEX(0, chsc_area, 32); 300 CHSC_LOG_HEX(0, chsc_area, 32);
297} 301}
@@ -355,13 +359,106 @@ static int chsc_ioctl_start(void __user *user_area)
355 if (copy_to_user(user_area, chsc_area, PAGE_SIZE)) 359 if (copy_to_user(user_area, chsc_area, PAGE_SIZE))
356 ret = -EFAULT; 360 ret = -EFAULT;
357out_free: 361out_free:
358 sprintf(dbf, "ret:%d", ret); 362 snprintf(dbf, sizeof(dbf), "ret:%d", ret);
359 CHSC_LOG(0, dbf); 363 CHSC_LOG(0, dbf);
360 kfree(request); 364 kfree(request);
361 free_page((unsigned long)chsc_area); 365 free_page((unsigned long)chsc_area);
362 return ret; 366 return ret;
363} 367}
364 368
369static int chsc_ioctl_on_close_set(void __user *user_area)
370{
371 char dbf[13];
372 int ret;
373
374 mutex_lock(&on_close_mutex);
375 if (on_close_chsc_area) {
376 ret = -EBUSY;
377 goto out_unlock;
378 }
379 on_close_request = kzalloc(sizeof(*on_close_request), GFP_KERNEL);
380 if (!on_close_request) {
381 ret = -ENOMEM;
382 goto out_unlock;
383 }
384 on_close_chsc_area = (void *)get_zeroed_page(GFP_DMA | GFP_KERNEL);
385 if (!on_close_chsc_area) {
386 ret = -ENOMEM;
387 goto out_free_request;
388 }
389 if (copy_from_user(on_close_chsc_area, user_area, PAGE_SIZE)) {
390 ret = -EFAULT;
391 goto out_free_chsc;
392 }
393 ret = 0;
394 goto out_unlock;
395
396out_free_chsc:
397 free_page((unsigned long)on_close_chsc_area);
398 on_close_chsc_area = NULL;
399out_free_request:
400 kfree(on_close_request);
401 on_close_request = NULL;
402out_unlock:
403 mutex_unlock(&on_close_mutex);
404 snprintf(dbf, sizeof(dbf), "ocsret:%d", ret);
405 CHSC_LOG(0, dbf);
406 return ret;
407}
408
409static int chsc_ioctl_on_close_remove(void)
410{
411 char dbf[13];
412 int ret;
413
414 mutex_lock(&on_close_mutex);
415 if (!on_close_chsc_area) {
416 ret = -ENOENT;
417 goto out_unlock;
418 }
419 free_page((unsigned long)on_close_chsc_area);
420 on_close_chsc_area = NULL;
421 kfree(on_close_request);
422 on_close_request = NULL;
423 ret = 0;
424out_unlock:
425 mutex_unlock(&on_close_mutex);
426 snprintf(dbf, sizeof(dbf), "ocrret:%d", ret);
427 CHSC_LOG(0, dbf);
428 return ret;
429}
430
431static int chsc_ioctl_start_sync(void __user *user_area)
432{
433 struct chsc_sync_area *chsc_area;
434 int ret, ccode;
435
436 chsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
437 if (!chsc_area)
438 return -ENOMEM;
439 if (copy_from_user(chsc_area, user_area, PAGE_SIZE)) {
440 ret = -EFAULT;
441 goto out_free;
442 }
443 if (chsc_area->header.code & 0x4000) {
444 ret = -EINVAL;
445 goto out_free;
446 }
447 chsc_log_command(chsc_area);
448 ccode = chsc(chsc_area);
449 if (ccode != 0) {
450 ret = -EIO;
451 goto out_free;
452 }
453 if (copy_to_user(user_area, chsc_area, PAGE_SIZE))
454 ret = -EFAULT;
455 else
456 ret = 0;
457out_free:
458 free_page((unsigned long)chsc_area);
459 return ret;
460}
461
365static int chsc_ioctl_info_channel_path(void __user *user_cd) 462static int chsc_ioctl_info_channel_path(void __user *user_cd)
366{ 463{
367 struct chsc_chp_cd *cd; 464 struct chsc_chp_cd *cd;
@@ -795,6 +892,8 @@ static long chsc_ioctl(struct file *filp, unsigned int cmd,
795 switch (cmd) { 892 switch (cmd) {
796 case CHSC_START: 893 case CHSC_START:
797 return chsc_ioctl_start(argp); 894 return chsc_ioctl_start(argp);
895 case CHSC_START_SYNC:
896 return chsc_ioctl_start_sync(argp);
798 case CHSC_INFO_CHANNEL_PATH: 897 case CHSC_INFO_CHANNEL_PATH:
799 return chsc_ioctl_info_channel_path(argp); 898 return chsc_ioctl_info_channel_path(argp);
800 case CHSC_INFO_CU: 899 case CHSC_INFO_CU:
@@ -809,14 +908,60 @@ static long chsc_ioctl(struct file *filp, unsigned int cmd,
809 return chsc_ioctl_chpd(argp); 908 return chsc_ioctl_chpd(argp);
810 case CHSC_INFO_DCAL: 909 case CHSC_INFO_DCAL:
811 return chsc_ioctl_dcal(argp); 910 return chsc_ioctl_dcal(argp);
911 case CHSC_ON_CLOSE_SET:
912 return chsc_ioctl_on_close_set(argp);
913 case CHSC_ON_CLOSE_REMOVE:
914 return chsc_ioctl_on_close_remove();
812 default: /* unknown ioctl number */ 915 default: /* unknown ioctl number */
813 return -ENOIOCTLCMD; 916 return -ENOIOCTLCMD;
814 } 917 }
815} 918}
816 919
920static atomic_t chsc_ready_for_use = ATOMIC_INIT(1);
921
922static int chsc_open(struct inode *inode, struct file *file)
923{
924 if (!atomic_dec_and_test(&chsc_ready_for_use)) {
925 atomic_inc(&chsc_ready_for_use);
926 return -EBUSY;
927 }
928 return nonseekable_open(inode, file);
929}
930
931static int chsc_release(struct inode *inode, struct file *filp)
932{
933 char dbf[13];
934 int ret;
935
936 mutex_lock(&on_close_mutex);
937 if (!on_close_chsc_area)
938 goto out_unlock;
939 init_completion(&on_close_request->completion);
940 CHSC_LOG(0, "on_close");
941 chsc_log_command(on_close_chsc_area);
942 spin_lock_irq(&chsc_lock);
943 ret = chsc_async(on_close_chsc_area, on_close_request);
944 spin_unlock_irq(&chsc_lock);
945 if (ret == -EINPROGRESS) {
946 wait_for_completion(&on_close_request->completion);
947 ret = chsc_examine_irb(on_close_request);
948 }
949 snprintf(dbf, sizeof(dbf), "relret:%d", ret);
950 CHSC_LOG(0, dbf);
951 free_page((unsigned long)on_close_chsc_area);
952 on_close_chsc_area = NULL;
953 kfree(on_close_request);
954 on_close_request = NULL;
955out_unlock:
956 mutex_unlock(&on_close_mutex);
957 atomic_inc(&chsc_ready_for_use);
958 return 0;
959}
960
817static const struct file_operations chsc_fops = { 961static const struct file_operations chsc_fops = {
818 .owner = THIS_MODULE, 962 .owner = THIS_MODULE,
819 .open = nonseekable_open, 963 .open = chsc_open,
964 .release = chsc_release,
820 .unlocked_ioctl = chsc_ioctl, 965 .unlocked_ioctl = chsc_ioctl,
821 .compat_ioctl = chsc_ioctl, 966 .compat_ioctl = chsc_ioctl,
822 .llseek = no_llseek, 967 .llseek = no_llseek,
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 935d80b4e9ce..4eeb4a6bf207 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -568,7 +568,7 @@ out:
568 */ 568 */
569void __irq_entry do_IRQ(struct pt_regs *regs) 569void __irq_entry do_IRQ(struct pt_regs *regs)
570{ 570{
571 struct tpi_info *tpi_info; 571 struct tpi_info *tpi_info = (struct tpi_info *) &regs->int_code;
572 struct subchannel *sch; 572 struct subchannel *sch;
573 struct irb *irb; 573 struct irb *irb;
574 struct pt_regs *old_regs; 574 struct pt_regs *old_regs;
@@ -579,46 +579,34 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
579 if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) 579 if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
580 /* Serve timer interrupts first. */ 580 /* Serve timer interrupts first. */
581 clock_comparator_work(); 581 clock_comparator_work();
582 /* 582
583 * Get interrupt information from lowcore 583 kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL);
584 */ 584 irb = (struct irb *) &S390_lowcore.irb;
585 tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id; 585 if (tpi_info->adapter_IO) {
586 irb = (struct irb *)&S390_lowcore.irb; 586 do_adapter_IO(tpi_info->isc);
587 do { 587 goto out;
588 kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL); 588 }
589 if (tpi_info->adapter_IO) { 589 sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
590 do_adapter_IO(tpi_info->isc); 590 if (!sch) {
591 continue; 591 /* Clear pending interrupt condition. */
592 } 592 inc_irq_stat(IRQIO_CIO);
593 sch = (struct subchannel *)(unsigned long)tpi_info->intparm; 593 tsch(tpi_info->schid, irb);
594 if (!sch) { 594 goto out;
595 /* Clear pending interrupt condition. */ 595 }
596 inc_irq_stat(IRQIO_CIO); 596 spin_lock(sch->lock);
597 tsch(tpi_info->schid, irb); 597 /* Store interrupt response block to lowcore. */
598 continue; 598 if (tsch(tpi_info->schid, irb) == 0) {
599 } 599 /* Keep subchannel information word up to date. */
600 spin_lock(sch->lock); 600 memcpy (&sch->schib.scsw, &irb->scsw, sizeof (irb->scsw));
601 /* Store interrupt response block to lowcore. */ 601 /* Call interrupt handler if there is one. */
602 if (tsch(tpi_info->schid, irb) == 0) { 602 if (sch->driver && sch->driver->irq)
603 /* Keep subchannel information word up to date. */ 603 sch->driver->irq(sch);
604 memcpy (&sch->schib.scsw, &irb->scsw, 604 else
605 sizeof (irb->scsw));
606 /* Call interrupt handler if there is one. */
607 if (sch->driver && sch->driver->irq)
608 sch->driver->irq(sch);
609 else
610 inc_irq_stat(IRQIO_CIO);
611 } else
612 inc_irq_stat(IRQIO_CIO); 605 inc_irq_stat(IRQIO_CIO);
613 spin_unlock(sch->lock); 606 } else
614 /* 607 inc_irq_stat(IRQIO_CIO);
615 * Are more interrupts pending? 608 spin_unlock(sch->lock);
616 * If so, the tpi instruction will update the lowcore 609out:
617 * to hold the info for the next interrupt.
618 * We don't do this for VM because a tpi drops the cpu
619 * out of the sie which costs more cycles than it saves.
620 */
621 } while (MACHINE_IS_LPAR && tpi(NULL) != 0);
622 irq_exit(); 610 irq_exit();
623 set_irq_regs(old_regs); 611 set_irq_regs(old_regs);
624} 612}
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 5132554d7917..8acaae18bd11 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -140,40 +140,6 @@ struct siga_flag {
140 u8:3; 140 u8:3;
141} __attribute__ ((packed)); 141} __attribute__ ((packed));
142 142
143struct chsc_ssqd_area {
144 struct chsc_header request;
145 u16:10;
146 u8 ssid:2;
147 u8 fmt:4;
148 u16 first_sch;
149 u16:16;
150 u16 last_sch;
151 u32:32;
152 struct chsc_header response;
153 u32:32;
154 struct qdio_ssqd_desc qdio_ssqd;
155} __attribute__ ((packed));
156
157struct scssc_area {
158 struct chsc_header request;
159 u16 operation_code;
160 u16:16;
161 u32:32;
162 u32:32;
163 u64 summary_indicator_addr;
164 u64 subchannel_indicator_addr;
165 u32 ks:4;
166 u32 kc:4;
167 u32:21;
168 u32 isc:3;
169 u32 word_with_d_bit;
170 u32:32;
171 struct subchannel_id schid;
172 u32 reserved[1004];
173 struct chsc_header response;
174 u32:32;
175} __attribute__ ((packed));
176
177struct qdio_dev_perf_stat { 143struct qdio_dev_perf_stat {
178 unsigned int adapter_int; 144 unsigned int adapter_int;
179 unsigned int qdio_int; 145 unsigned int qdio_int;
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 843051bc20f1..fb1c1e0483ed 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -608,50 +608,6 @@ static inline int contains_aobs(struct qdio_q *q)
608 return !q->is_input_q && q->u.out.use_cq; 608 return !q->is_input_q && q->u.out.use_cq;
609} 609}
610 610
611static inline void qdio_trace_aob(struct qdio_irq *irq, struct qdio_q *q,
612 int i, struct qaob *aob)
613{
614 int tmp;
615
616 DBF_DEV_EVENT(DBF_INFO, irq, "AOB%d:%lx", i,
617 (unsigned long) virt_to_phys(aob));
618 DBF_DEV_EVENT(DBF_INFO, irq, "RES00:%lx",
619 (unsigned long) aob->res0[0]);
620 DBF_DEV_EVENT(DBF_INFO, irq, "RES01:%lx",
621 (unsigned long) aob->res0[1]);
622 DBF_DEV_EVENT(DBF_INFO, irq, "RES02:%lx",
623 (unsigned long) aob->res0[2]);
624 DBF_DEV_EVENT(DBF_INFO, irq, "RES03:%lx",
625 (unsigned long) aob->res0[3]);
626 DBF_DEV_EVENT(DBF_INFO, irq, "RES04:%lx",
627 (unsigned long) aob->res0[4]);
628 DBF_DEV_EVENT(DBF_INFO, irq, "RES05:%lx",
629 (unsigned long) aob->res0[5]);
630 DBF_DEV_EVENT(DBF_INFO, irq, "RES1:%x", aob->res1);
631 DBF_DEV_EVENT(DBF_INFO, irq, "RES2:%x", aob->res2);
632 DBF_DEV_EVENT(DBF_INFO, irq, "RES3:%x", aob->res3);
633 DBF_DEV_EVENT(DBF_INFO, irq, "AORC:%u", aob->aorc);
634 DBF_DEV_EVENT(DBF_INFO, irq, "FLAGS:%u", aob->flags);
635 DBF_DEV_EVENT(DBF_INFO, irq, "CBTBS:%u", aob->cbtbs);
636 DBF_DEV_EVENT(DBF_INFO, irq, "SBC:%u", aob->sb_count);
637 for (tmp = 0; tmp < QDIO_MAX_ELEMENTS_PER_BUFFER; ++tmp) {
638 DBF_DEV_EVENT(DBF_INFO, irq, "SBA%d:%lx", tmp,
639 (unsigned long) aob->sba[tmp]);
640 DBF_DEV_EVENT(DBF_INFO, irq, "rSBA%d:%lx", tmp,
641 (unsigned long) q->sbal[i]->element[tmp].addr);
642 DBF_DEV_EVENT(DBF_INFO, irq, "DC%d:%u", tmp, aob->dcount[tmp]);
643 DBF_DEV_EVENT(DBF_INFO, irq, "rDC%d:%u", tmp,
644 q->sbal[i]->element[tmp].length);
645 }
646 DBF_DEV_EVENT(DBF_INFO, irq, "USER0:%lx", (unsigned long) aob->user0);
647 for (tmp = 0; tmp < 2; ++tmp) {
648 DBF_DEV_EVENT(DBF_INFO, irq, "RES4%d:%lx", tmp,
649 (unsigned long) aob->res4[tmp]);
650 }
651 DBF_DEV_EVENT(DBF_INFO, irq, "USER1:%lx", (unsigned long) aob->user1);
652 DBF_DEV_EVENT(DBF_INFO, irq, "USER2:%lx", (unsigned long) aob->user2);
653}
654
655static inline void qdio_handle_aobs(struct qdio_q *q, int start, int count) 611static inline void qdio_handle_aobs(struct qdio_q *q, int start, int count)
656{ 612{
657 unsigned char state = 0; 613 unsigned char state = 0;
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 16ecd35b8e51..f5f4a91fab44 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -254,40 +254,31 @@ int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr,
254 int rc; 254 int rc;
255 255
256 DBF_EVENT("getssqd:%4x", schid->sch_no); 256 DBF_EVENT("getssqd:%4x", schid->sch_no);
257 if (irq_ptr != NULL) 257 if (!irq_ptr) {
258 ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page;
259 else
260 ssqd = (struct chsc_ssqd_area *)__get_free_page(GFP_KERNEL); 258 ssqd = (struct chsc_ssqd_area *)__get_free_page(GFP_KERNEL);
261 memset(ssqd, 0, PAGE_SIZE); 259 if (!ssqd)
262 260 return -ENOMEM;
263 ssqd->request = (struct chsc_header) { 261 } else {
264 .length = 0x0010, 262 ssqd = (struct chsc_ssqd_area *)irq_ptr->chsc_page;
265 .code = 0x0024, 263 }
266 }; 264
267 ssqd->first_sch = schid->sch_no; 265 rc = chsc_ssqd(*schid, ssqd);
268 ssqd->last_sch = schid->sch_no;
269 ssqd->ssid = schid->ssid;
270
271 if (chsc(ssqd))
272 return -EIO;
273 rc = chsc_error_from_response(ssqd->response.code);
274 if (rc) 266 if (rc)
275 return rc; 267 goto out;
276 268
277 if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) || 269 if (!(ssqd->qdio_ssqd.flags & CHSC_FLAG_QDIO_CAPABILITY) ||
278 !(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) || 270 !(ssqd->qdio_ssqd.flags & CHSC_FLAG_VALIDITY) ||
279 (ssqd->qdio_ssqd.sch != schid->sch_no)) 271 (ssqd->qdio_ssqd.sch != schid->sch_no))
280 return -EINVAL; 272 rc = -EINVAL;
281 273
282 if (irq_ptr != NULL) 274 if (!rc)
283 memcpy(&irq_ptr->ssqd_desc, &ssqd->qdio_ssqd, 275 memcpy(data, &ssqd->qdio_ssqd, sizeof(*data));
284 sizeof(struct qdio_ssqd_desc)); 276
285 else { 277out:
286 memcpy(data, &ssqd->qdio_ssqd, 278 if (!irq_ptr)
287 sizeof(struct qdio_ssqd_desc));
288 free_page((unsigned long)ssqd); 279 free_page((unsigned long)ssqd);
289 } 280
290 return 0; 281 return rc;
291} 282}
292 283
293void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr) 284void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
@@ -295,7 +286,7 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
295 unsigned char qdioac; 286 unsigned char qdioac;
296 int rc; 287 int rc;
297 288
298 rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, NULL); 289 rc = qdio_setup_get_ssqd(irq_ptr, &irq_ptr->schid, &irq_ptr->ssqd_desc);
299 if (rc) { 290 if (rc) {
300 DBF_ERROR("%4x ssqd ERR", irq_ptr->schid.sch_no); 291 DBF_ERROR("%4x ssqd ERR", irq_ptr->schid.sch_no);
301 DBF_ERROR("rc:%x", rc); 292 DBF_ERROR("rc:%x", rc);
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index bde5255200dc..5d06253c2a7a 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -36,8 +36,13 @@ struct indicator_t {
36static LIST_HEAD(tiq_list); 36static LIST_HEAD(tiq_list);
37static DEFINE_MUTEX(tiq_list_lock); 37static DEFINE_MUTEX(tiq_list_lock);
38 38
39/* adapter local summary indicator */ 39/* Adapter interrupt definitions */
40static u8 *tiqdio_alsi; 40static void tiqdio_thinint_handler(struct airq_struct *airq);
41
42static struct airq_struct tiqdio_airq = {
43 .handler = tiqdio_thinint_handler,
44 .isc = QDIO_AIRQ_ISC,
45};
41 46
42static struct indicator_t *q_indicators; 47static struct indicator_t *q_indicators;
43 48
@@ -176,7 +181,7 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
176 * @alsi: pointer to adapter local summary indicator 181 * @alsi: pointer to adapter local summary indicator
177 * @data: NULL 182 * @data: NULL
178 */ 183 */
179static void tiqdio_thinint_handler(void *alsi, void *data) 184static void tiqdio_thinint_handler(struct airq_struct *airq)
180{ 185{
181 u32 si_used = clear_shared_ind(); 186 u32 si_used = clear_shared_ind();
182 struct qdio_q *q; 187 struct qdio_q *q;
@@ -208,51 +213,31 @@ static void tiqdio_thinint_handler(void *alsi, void *data)
208 213
209static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset) 214static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset)
210{ 215{
211 struct scssc_area *scssc_area; 216 struct chsc_scssc_area *scssc = (void *)irq_ptr->chsc_page;
217 u64 summary_indicator_addr, subchannel_indicator_addr;
212 int rc; 218 int rc;
213 219
214 scssc_area = (struct scssc_area *)irq_ptr->chsc_page;
215 memset(scssc_area, 0, PAGE_SIZE);
216
217 if (reset) { 220 if (reset) {
218 scssc_area->summary_indicator_addr = 0; 221 summary_indicator_addr = 0;
219 scssc_area->subchannel_indicator_addr = 0; 222 subchannel_indicator_addr = 0;
220 } else { 223 } else {
221 scssc_area->summary_indicator_addr = virt_to_phys(tiqdio_alsi); 224 summary_indicator_addr = virt_to_phys(tiqdio_airq.lsi_ptr);
222 scssc_area->subchannel_indicator_addr = 225 subchannel_indicator_addr = virt_to_phys(irq_ptr->dsci);
223 virt_to_phys(irq_ptr->dsci);
224 } 226 }
225 227
226 scssc_area->request = (struct chsc_header) { 228 rc = chsc_sadc(irq_ptr->schid, scssc, summary_indicator_addr,
227 .length = 0x0fe0, 229 subchannel_indicator_addr);
228 .code = 0x0021,
229 };
230 scssc_area->operation_code = 0;
231 scssc_area->ks = PAGE_DEFAULT_KEY >> 4;
232 scssc_area->kc = PAGE_DEFAULT_KEY >> 4;
233 scssc_area->isc = QDIO_AIRQ_ISC;
234 scssc_area->schid = irq_ptr->schid;
235
236 /* enable the time delay disablement facility */
237 if (css_general_characteristics.aif_tdd)
238 scssc_area->word_with_d_bit = 0x10000000;
239
240 rc = chsc(scssc_area);
241 if (rc)
242 return -EIO;
243
244 rc = chsc_error_from_response(scssc_area->response.code);
245 if (rc) { 230 if (rc) {
246 DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no, 231 DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no,
247 scssc_area->response.code); 232 scssc->response.code);
248 DBF_ERROR_HEX(&scssc_area->response, sizeof(void *)); 233 goto out;
249 return rc;
250 } 234 }
251 235
252 DBF_EVENT("setscind"); 236 DBF_EVENT("setscind");
253 DBF_HEX(&scssc_area->summary_indicator_addr, sizeof(unsigned long)); 237 DBF_HEX(&summary_indicator_addr, sizeof(summary_indicator_addr));
254 DBF_HEX(&scssc_area->subchannel_indicator_addr, sizeof(unsigned long)); 238 DBF_HEX(&subchannel_indicator_addr, sizeof(subchannel_indicator_addr));
255 return 0; 239out:
240 return rc;
256} 241}
257 242
258/* allocate non-shared indicators and shared indicator */ 243/* allocate non-shared indicators and shared indicator */
@@ -272,14 +257,12 @@ void tiqdio_free_memory(void)
272 257
273int __init tiqdio_register_thinints(void) 258int __init tiqdio_register_thinints(void)
274{ 259{
275 isc_register(QDIO_AIRQ_ISC); 260 int rc;
276 tiqdio_alsi = s390_register_adapter_interrupt(&tiqdio_thinint_handler, 261
277 NULL, QDIO_AIRQ_ISC); 262 rc = register_adapter_interrupt(&tiqdio_airq);
278 if (IS_ERR(tiqdio_alsi)) { 263 if (rc) {
279 DBF_EVENT("RTI:%lx", PTR_ERR(tiqdio_alsi)); 264 DBF_EVENT("RTI:%x", rc);
280 tiqdio_alsi = NULL; 265 return rc;
281 isc_unregister(QDIO_AIRQ_ISC);
282 return -ENOMEM;
283 } 266 }
284 return 0; 267 return 0;
285} 268}
@@ -312,9 +295,5 @@ void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
312void __exit tiqdio_unregister_thinints(void) 295void __exit tiqdio_unregister_thinints(void)
313{ 296{
314 WARN_ON(!list_empty(&tiq_list)); 297 WARN_ON(!list_empty(&tiq_list));
315 298 unregister_adapter_interrupt(&tiqdio_airq);
316 if (tiqdio_alsi) {
317 s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC);
318 isc_unregister(QDIO_AIRQ_ISC);
319 }
320} 299}
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 9de41aa14896..f446a7705c3b 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -58,7 +58,7 @@ static inline void ap_schedule_poll_timer(void);
58static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags); 58static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags);
59static int ap_device_remove(struct device *dev); 59static int ap_device_remove(struct device *dev);
60static int ap_device_probe(struct device *dev); 60static int ap_device_probe(struct device *dev);
61static void ap_interrupt_handler(void *unused1, void *unused2); 61static void ap_interrupt_handler(struct airq_struct *airq);
62static void ap_reset(struct ap_device *ap_dev); 62static void ap_reset(struct ap_device *ap_dev);
63static void ap_config_timeout(unsigned long ptr); 63static void ap_config_timeout(unsigned long ptr);
64static int ap_select_domain(void); 64static int ap_select_domain(void);
@@ -106,7 +106,6 @@ static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
106static struct task_struct *ap_poll_kthread = NULL; 106static struct task_struct *ap_poll_kthread = NULL;
107static DEFINE_MUTEX(ap_poll_thread_mutex); 107static DEFINE_MUTEX(ap_poll_thread_mutex);
108static DEFINE_SPINLOCK(ap_poll_timer_lock); 108static DEFINE_SPINLOCK(ap_poll_timer_lock);
109static void *ap_interrupt_indicator;
110static struct hrtimer ap_poll_timer; 109static struct hrtimer ap_poll_timer;
111/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds. 110/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
112 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/ 111 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
@@ -120,13 +119,21 @@ static int ap_suspend_flag;
120static int user_set_domain = 0; 119static int user_set_domain = 0;
121static struct bus_type ap_bus_type; 120static struct bus_type ap_bus_type;
122 121
122/* Adapter interrupt definitions */
123static int ap_airq_flag;
124
125static struct airq_struct ap_airq = {
126 .handler = ap_interrupt_handler,
127 .isc = AP_ISC,
128};
129
123/** 130/**
124 * ap_using_interrupts() - Returns non-zero if interrupt support is 131 * ap_using_interrupts() - Returns non-zero if interrupt support is
125 * available. 132 * available.
126 */ 133 */
127static inline int ap_using_interrupts(void) 134static inline int ap_using_interrupts(void)
128{ 135{
129 return ap_interrupt_indicator != NULL; 136 return ap_airq_flag;
130} 137}
131 138
132/** 139/**
@@ -588,7 +595,7 @@ static int ap_init_queue(ap_qid_t qid)
588 } 595 }
589 } 596 }
590 if (rc == 0 && ap_using_interrupts()) { 597 if (rc == 0 && ap_using_interrupts()) {
591 rc = ap_queue_enable_interruption(qid, ap_interrupt_indicator); 598 rc = ap_queue_enable_interruption(qid, ap_airq.lsi_ptr);
592 /* If interruption mode is supported by the machine, 599 /* If interruption mode is supported by the machine,
593 * but an AP can not be enabled for interruption then 600 * but an AP can not be enabled for interruption then
594 * the AP will be discarded. */ 601 * the AP will be discarded. */
@@ -821,13 +828,22 @@ static int ap_bus_suspend(struct device *dev, pm_message_t state)
821 828
822static int ap_bus_resume(struct device *dev) 829static int ap_bus_resume(struct device *dev)
823{ 830{
824 int rc = 0;
825 struct ap_device *ap_dev = to_ap_dev(dev); 831 struct ap_device *ap_dev = to_ap_dev(dev);
832 int rc;
826 833
827 if (ap_suspend_flag) { 834 if (ap_suspend_flag) {
828 ap_suspend_flag = 0; 835 ap_suspend_flag = 0;
829 if (!ap_interrupts_available()) 836 if (ap_interrupts_available()) {
830 ap_interrupt_indicator = NULL; 837 if (!ap_using_interrupts()) {
838 rc = register_adapter_interrupt(&ap_airq);
839 ap_airq_flag = (rc == 0);
840 }
841 } else {
842 if (ap_using_interrupts()) {
843 unregister_adapter_interrupt(&ap_airq);
844 ap_airq_flag = 0;
845 }
846 }
831 ap_query_configuration(); 847 ap_query_configuration();
832 if (!user_set_domain) { 848 if (!user_set_domain) {
833 ap_domain_index = -1; 849 ap_domain_index = -1;
@@ -848,7 +864,10 @@ static int ap_bus_resume(struct device *dev)
848 tasklet_schedule(&ap_tasklet); 864 tasklet_schedule(&ap_tasklet);
849 if (ap_thread_flag) 865 if (ap_thread_flag)
850 rc = ap_poll_thread_start(); 866 rc = ap_poll_thread_start();
851 } 867 else
868 rc = 0;
869 } else
870 rc = 0;
852 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) { 871 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
853 spin_lock_bh(&ap_dev->lock); 872 spin_lock_bh(&ap_dev->lock);
854 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid), 873 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
@@ -1266,7 +1285,7 @@ out:
1266 return rc; 1285 return rc;
1267} 1286}
1268 1287
1269static void ap_interrupt_handler(void *unused1, void *unused2) 1288static void ap_interrupt_handler(struct airq_struct *airq)
1270{ 1289{
1271 inc_irq_stat(IRQIO_APB); 1290 inc_irq_stat(IRQIO_APB);
1272 tasklet_schedule(&ap_tasklet); 1291 tasklet_schedule(&ap_tasklet);
@@ -1722,7 +1741,7 @@ static void ap_poll_all(unsigned long dummy)
1722 * important that no requests on any AP get lost. 1741 * important that no requests on any AP get lost.
1723 */ 1742 */
1724 if (ap_using_interrupts()) 1743 if (ap_using_interrupts())
1725 xchg((u8 *)ap_interrupt_indicator, 0); 1744 xchg(ap_airq.lsi_ptr, 0);
1726 do { 1745 do {
1727 flags = 0; 1746 flags = 0;
1728 spin_lock(&ap_device_list_lock); 1747 spin_lock(&ap_device_list_lock);
@@ -1795,7 +1814,7 @@ static int ap_poll_thread_start(void)
1795 mutex_lock(&ap_poll_thread_mutex); 1814 mutex_lock(&ap_poll_thread_mutex);
1796 if (!ap_poll_kthread) { 1815 if (!ap_poll_kthread) {
1797 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll"); 1816 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
1798 rc = IS_ERR(ap_poll_kthread) ? PTR_ERR(ap_poll_kthread) : 0; 1817 rc = PTR_RET(ap_poll_kthread);
1799 if (rc) 1818 if (rc)
1800 ap_poll_kthread = NULL; 1819 ap_poll_kthread = NULL;
1801 } 1820 }
@@ -1881,13 +1900,8 @@ int __init ap_module_init(void)
1881 return -ENODEV; 1900 return -ENODEV;
1882 } 1901 }
1883 if (ap_interrupts_available()) { 1902 if (ap_interrupts_available()) {
1884 isc_register(AP_ISC); 1903 rc = register_adapter_interrupt(&ap_airq);
1885 ap_interrupt_indicator = s390_register_adapter_interrupt( 1904 ap_airq_flag = (rc == 0);
1886 &ap_interrupt_handler, NULL, AP_ISC);
1887 if (IS_ERR(ap_interrupt_indicator)) {
1888 ap_interrupt_indicator = NULL;
1889 isc_unregister(AP_ISC);
1890 }
1891 } 1905 }
1892 1906
1893 register_reset_call(&ap_reset_call); 1907 register_reset_call(&ap_reset_call);
@@ -1904,7 +1918,7 @@ int __init ap_module_init(void)
1904 1918
1905 /* Create /sys/devices/ap. */ 1919 /* Create /sys/devices/ap. */
1906 ap_root_device = root_device_register("ap"); 1920 ap_root_device = root_device_register("ap");
1907 rc = IS_ERR(ap_root_device) ? PTR_ERR(ap_root_device) : 0; 1921 rc = PTR_RET(ap_root_device);
1908 if (rc) 1922 if (rc)
1909 goto out_bus; 1923 goto out_bus;
1910 1924
@@ -1955,10 +1969,8 @@ out_bus:
1955 bus_unregister(&ap_bus_type); 1969 bus_unregister(&ap_bus_type);
1956out: 1970out:
1957 unregister_reset_call(&ap_reset_call); 1971 unregister_reset_call(&ap_reset_call);
1958 if (ap_using_interrupts()) { 1972 if (ap_using_interrupts())
1959 s390_unregister_adapter_interrupt(ap_interrupt_indicator, AP_ISC); 1973 unregister_adapter_interrupt(&ap_airq);
1960 isc_unregister(AP_ISC);
1961 }
1962 return rc; 1974 return rc;
1963} 1975}
1964 1976
@@ -1994,10 +2006,8 @@ void ap_module_exit(void)
1994 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]); 2006 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1995 bus_unregister(&ap_bus_type); 2007 bus_unregister(&ap_bus_type);
1996 unregister_reset_call(&ap_reset_call); 2008 unregister_reset_call(&ap_reset_call);
1997 if (ap_using_interrupts()) { 2009 if (ap_using_interrupts())
1998 s390_unregister_adapter_interrupt(ap_interrupt_indicator, AP_ISC); 2010 unregister_adapter_interrupt(&ap_airq);
1999 isc_unregister(AP_ISC);
2000 }
2001} 2011}
2002 2012
2003module_init(ap_module_init); 2013module_init(ap_module_init);
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 83bc9c5fa0c1..fd7b3bd80789 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -3348,7 +3348,7 @@ static int __init claw_init(void)
3348 } 3348 }
3349 CLAW_DBF_TEXT(2, setup, "init_mod"); 3349 CLAW_DBF_TEXT(2, setup, "init_mod");
3350 claw_root_dev = root_device_register("claw"); 3350 claw_root_dev = root_device_register("claw");
3351 ret = IS_ERR(claw_root_dev) ? PTR_ERR(claw_root_dev) : 0; 3351 ret = PTR_RET(claw_root_dev);
3352 if (ret) 3352 if (ret)
3353 goto register_err; 3353 goto register_err;
3354 ret = ccw_driver_register(&claw_ccw_driver); 3354 ret = ccw_driver_register(&claw_ccw_driver);
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 676f12049a36..70b3a023100e 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1837,7 +1837,7 @@ static int __init ctcm_init(void)
1837 if (ret) 1837 if (ret)
1838 goto out_err; 1838 goto out_err;
1839 ctcm_root_dev = root_device_register("ctcm"); 1839 ctcm_root_dev = root_device_register("ctcm");
1840 ret = IS_ERR(ctcm_root_dev) ? PTR_ERR(ctcm_root_dev) : 0; 1840 ret = PTR_RET(ctcm_root_dev);
1841 if (ret) 1841 if (ret)
1842 goto register_err; 1842 goto register_err;
1843 ret = ccw_driver_register(&ctcm_ccw_driver); 1843 ret = ccw_driver_register(&ctcm_ccw_driver);
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index c645dc9e98af..f404f55b3191 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -2441,7 +2441,7 @@ __init lcs_init_module(void)
2441 if (rc) 2441 if (rc)
2442 goto out_err; 2442 goto out_err;
2443 lcs_root_dev = root_device_register("lcs"); 2443 lcs_root_dev = root_device_register("lcs");
2444 rc = IS_ERR(lcs_root_dev) ? PTR_ERR(lcs_root_dev) : 0; 2444 rc = PTR_RET(lcs_root_dev);
2445 if (rc) 2445 if (rc)
2446 goto register_err; 2446 goto register_err;
2447 rc = ccw_driver_register(&lcs_ccw_driver); 2447 rc = ccw_driver_register(&lcs_ccw_driver);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 6cd0fc1b203a..70ce6b6fce3b 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -5705,7 +5705,7 @@ static int __init qeth_core_init(void)
5705 if (rc) 5705 if (rc)
5706 goto out_err; 5706 goto out_err;
5707 qeth_core_root_dev = root_device_register("qeth"); 5707 qeth_core_root_dev = root_device_register("qeth");
5708 rc = IS_ERR(qeth_core_root_dev) ? PTR_ERR(qeth_core_root_dev) : 0; 5708 rc = PTR_RET(qeth_core_root_dev);
5709 if (rc) 5709 if (rc)
5710 goto register_err; 5710 goto register_err;
5711 qeth_core_header_cache = kmem_cache_create("qeth_hdr", 5711 qeth_core_header_cache = kmem_cache_create("qeth_hdr",