aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-31 19:14:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-31 19:14:20 -0400
commit32087d4eeca14b82660dab288b1d659963b954bd (patch)
tree8c131ca9bf08f88d3b02e1937b795a42f8951d79 /drivers
parentb1c907f3b2675ecb01e340948fc62d6535ff5ac3 (diff)
parent07ea815b22b9f70ec8de6ddf8db63a1dd1585caf (diff)
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (54 commits) [S390] Remove error checking from copy_oldmem_page() [S390] qdio: prevent dsci access without adapter interrupts [S390] irqstats: split IPI interrupt accounting [S390] add missing __tlb_flush_global() for !CONFIG_SMP [S390] sparse: fix sparse symbol shadow warning [S390] sparse: fix sparse NULL pointer warnings [S390] sparse: fix sparse warnings with __user pointers [S390] sparse: fix sparse warnings in math-emu [S390] sparse: fix sparse warnings about missing prototypes [S390] sparse: fix sparse ANSI-C warnings [S390] sparse: fix sparse static warnings [S390] sparse: fix access past end of array warnings [S390] dasd: prevent path verification before resume [S390] qdio: remove multicast polling [S390] qdio: reset outbound SBAL error states [S390] qdio: EQBS retry after CCQ 96 [S390] qdio: add timestamp for last queue scan time [S390] Introduce get_clock_fast() [S390] kvm: Handle diagnose 0x10 (release pages) [S390] take mmap_sem when walking guest page table ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/block/dasd.c19
-rw-r--r--drivers/s390/block/dasd_eckd.c45
-rw-r--r--drivers/s390/block/dasd_fba.c1
-rw-r--r--drivers/s390/block/dasd_int.h2
-rw-r--r--drivers/s390/char/con3215.c3
-rw-r--r--drivers/s390/char/raw3270.c3
-rw-r--r--drivers/s390/char/sclp_cmd.c4
-rw-r--r--drivers/s390/char/sclp_quiesce.c3
-rw-r--r--drivers/s390/char/tape_34xx.c1
-rw-r--r--drivers/s390/char/tape_3590.c1
-rw-r--r--drivers/s390/char/tape_core.c2
-rw-r--r--drivers/s390/char/vmur.c3
-rw-r--r--drivers/s390/char/zcore.c21
-rw-r--r--drivers/s390/cio/ccwgroup.c333
-rw-r--r--drivers/s390/cio/ccwreq.c23
-rw-r--r--drivers/s390/cio/chsc_sch.c5
-rw-r--r--drivers/s390/cio/cio.c19
-rw-r--r--drivers/s390/cio/css.h2
-rw-r--r--drivers/s390/cio/device.c13
-rw-r--r--drivers/s390/cio/device.h13
-rw-r--r--drivers/s390/cio/io_sch.h2
-rw-r--r--drivers/s390/cio/qdio.h40
-rw-r--r--drivers/s390/cio/qdio_debug.c10
-rw-r--r--drivers/s390/cio/qdio_main.c102
-rw-r--r--drivers/s390/cio/qdio_thinint.c52
-rw-r--r--drivers/s390/kvm/kvm_virtio.c8
-rw-r--r--drivers/s390/net/claw.c3
-rw-r--r--drivers/s390/net/ctcm_main.c3
-rw-r--r--drivers/s390/net/ctcm_sysfs.c2
-rw-r--r--drivers/s390/net/lcs.c5
-rw-r--r--drivers/s390/net/qeth_l3_main.c2
31 files changed, 395 insertions, 350 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index a1d3ddba99cc..65894f05a801 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -11,7 +11,6 @@
11#define KMSG_COMPONENT "dasd" 11#define KMSG_COMPONENT "dasd"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13 13
14#include <linux/kernel_stat.h>
15#include <linux/kmod.h> 14#include <linux/kmod.h>
16#include <linux/init.h> 15#include <linux/init.h>
17#include <linux/interrupt.h> 16#include <linux/interrupt.h>
@@ -1594,7 +1593,6 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1594 unsigned long long now; 1593 unsigned long long now;
1595 int expires; 1594 int expires;
1596 1595
1597 kstat_cpu(smp_processor_id()).irqs[IOINT_DAS]++;
1598 if (IS_ERR(irb)) { 1596 if (IS_ERR(irb)) {
1599 switch (PTR_ERR(irb)) { 1597 switch (PTR_ERR(irb)) {
1600 case -EIO: 1598 case -EIO:
@@ -2061,13 +2059,14 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr)
2061/* 2059/*
2062 * Wakeup helper for the 'sleep_on' functions. 2060 * Wakeup helper for the 'sleep_on' functions.
2063 */ 2061 */
2064static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) 2062void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data)
2065{ 2063{
2066 spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev)); 2064 spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev));
2067 cqr->callback_data = DASD_SLEEPON_END_TAG; 2065 cqr->callback_data = DASD_SLEEPON_END_TAG;
2068 spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev)); 2066 spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev));
2069 wake_up(&generic_waitq); 2067 wake_up(&generic_waitq);
2070} 2068}
2069EXPORT_SYMBOL_GPL(dasd_wakeup_cb);
2071 2070
2072static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) 2071static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
2073{ 2072{
@@ -2167,7 +2166,9 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
2167 } else 2166 } else
2168 wait_event(generic_waitq, !(device->stopped)); 2167 wait_event(generic_waitq, !(device->stopped));
2169 2168
2170 cqr->callback = dasd_wakeup_cb; 2169 if (!cqr->callback)
2170 cqr->callback = dasd_wakeup_cb;
2171
2171 cqr->callback_data = DASD_SLEEPON_START_TAG; 2172 cqr->callback_data = DASD_SLEEPON_START_TAG;
2172 dasd_add_request_tail(cqr); 2173 dasd_add_request_tail(cqr);
2173 if (interruptible) { 2174 if (interruptible) {
@@ -2263,7 +2264,11 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
2263 cqr->callback = dasd_wakeup_cb; 2264 cqr->callback = dasd_wakeup_cb;
2264 cqr->callback_data = DASD_SLEEPON_START_TAG; 2265 cqr->callback_data = DASD_SLEEPON_START_TAG;
2265 cqr->status = DASD_CQR_QUEUED; 2266 cqr->status = DASD_CQR_QUEUED;
2266 list_add(&cqr->devlist, &device->ccw_queue); 2267 /*
2268 * add new request as second
2269 * first the terminated cqr needs to be finished
2270 */
2271 list_add(&cqr->devlist, device->ccw_queue.next);
2267 2272
2268 /* let the bh start the request to keep them in order */ 2273 /* let the bh start the request to keep them in order */
2269 dasd_schedule_device_bh(device); 2274 dasd_schedule_device_bh(device);
@@ -3284,6 +3289,9 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev)
3284 if (IS_ERR(device)) 3289 if (IS_ERR(device))
3285 return PTR_ERR(device); 3290 return PTR_ERR(device);
3286 3291
3292 /* mark device as suspended */
3293 set_bit(DASD_FLAG_SUSPENDED, &device->flags);
3294
3287 if (device->discipline->freeze) 3295 if (device->discipline->freeze)
3288 rc = device->discipline->freeze(device); 3296 rc = device->discipline->freeze(device);
3289 3297
@@ -3358,6 +3366,7 @@ int dasd_generic_restore_device(struct ccw_device *cdev)
3358 if (device->block) 3366 if (device->block)
3359 dasd_schedule_block_bh(device->block); 3367 dasd_schedule_block_bh(device->block);
3360 3368
3369 clear_bit(DASD_FLAG_SUSPENDED, &device->flags);
3361 dasd_put_device(device); 3370 dasd_put_device(device);
3362 return 0; 3371 return 0;
3363} 3372}
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 6e835c9fdfcb..6ab29680586a 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -844,6 +844,30 @@ static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,
844 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags); 844 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);
845} 845}
846 846
847/*
848 * Wakeup helper for read_conf
849 * if the cqr is not done and needs some error recovery
850 * the buffer has to be re-initialized with the EBCDIC "V1.0"
851 * to show support for virtual device SNEQ
852 */
853static void read_conf_cb(struct dasd_ccw_req *cqr, void *data)
854{
855 struct ccw1 *ccw;
856 __u8 *rcd_buffer;
857
858 if (cqr->status != DASD_CQR_DONE) {
859 ccw = cqr->cpaddr;
860 rcd_buffer = (__u8 *)((addr_t) ccw->cda);
861 memset(rcd_buffer, 0, sizeof(*rcd_buffer));
862
863 rcd_buffer[0] = 0xE5;
864 rcd_buffer[1] = 0xF1;
865 rcd_buffer[2] = 0x4B;
866 rcd_buffer[3] = 0xF0;
867 }
868 dasd_wakeup_cb(cqr, data);
869}
870
847static int dasd_eckd_read_conf_immediately(struct dasd_device *device, 871static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
848 struct dasd_ccw_req *cqr, 872 struct dasd_ccw_req *cqr,
849 __u8 *rcd_buffer, 873 __u8 *rcd_buffer,
@@ -863,6 +887,7 @@ static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
863 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 887 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
864 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags); 888 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
865 cqr->retries = 5; 889 cqr->retries = 5;
890 cqr->callback = read_conf_cb;
866 rc = dasd_sleep_on_immediatly(cqr); 891 rc = dasd_sleep_on_immediatly(cqr);
867 return rc; 892 return rc;
868} 893}
@@ -900,6 +925,7 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
900 goto out_error; 925 goto out_error;
901 } 926 }
902 dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm); 927 dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm);
928 cqr->callback = read_conf_cb;
903 ret = dasd_sleep_on(cqr); 929 ret = dasd_sleep_on(cqr);
904 /* 930 /*
905 * on success we update the user input parms 931 * on success we update the user input parms
@@ -1075,6 +1101,12 @@ static void do_path_verification_work(struct work_struct *work)
1075 data = container_of(work, struct path_verification_work_data, worker); 1101 data = container_of(work, struct path_verification_work_data, worker);
1076 device = data->device; 1102 device = data->device;
1077 1103
1104 /* delay path verification until device was resumed */
1105 if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
1106 schedule_work(work);
1107 return;
1108 }
1109
1078 opm = 0; 1110 opm = 0;
1079 npm = 0; 1111 npm = 0;
1080 ppm = 0; 1112 ppm = 0;
@@ -2021,9 +2053,13 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device,
2021 /* first of all check for state change pending interrupt */ 2053 /* first of all check for state change pending interrupt */
2022 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; 2054 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
2023 if ((scsw_dstat(&irb->scsw) & mask) == mask) { 2055 if ((scsw_dstat(&irb->scsw) & mask) == mask) {
2024 /* for alias only and not in offline processing*/ 2056 /*
2057 * for alias only, not in offline processing
2058 * and only if not suspended
2059 */
2025 if (!device->block && private->lcu && 2060 if (!device->block && private->lcu &&
2026 !test_bit(DASD_FLAG_OFFLINE, &device->flags)) { 2061 !test_bit(DASD_FLAG_OFFLINE, &device->flags) &&
2062 !test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
2027 /* 2063 /*
2028 * the state change could be caused by an alias 2064 * the state change could be caused by an alias
2029 * reassignment remove device from alias handling 2065 * reassignment remove device from alias handling
@@ -2350,7 +2386,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
2350 new_track = 1; 2386 new_track = 1;
2351 end_idaw = 0; 2387 end_idaw = 0;
2352 len_to_track_end = 0; 2388 len_to_track_end = 0;
2353 idaw_dst = 0; 2389 idaw_dst = NULL;
2354 idaw_len = 0; 2390 idaw_len = 0;
2355 rq_for_each_segment(bv, req, iter) { 2391 rq_for_each_segment(bv, req, iter) {
2356 dst = page_address(bv->bv_page) + bv->bv_offset; 2392 dst = page_address(bv->bv_page) + bv->bv_offset;
@@ -2412,7 +2448,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
2412 if (end_idaw) { 2448 if (end_idaw) {
2413 idaws = idal_create_words(idaws, idaw_dst, 2449 idaws = idal_create_words(idaws, idaw_dst,
2414 idaw_len); 2450 idaw_len);
2415 idaw_dst = 0; 2451 idaw_dst = NULL;
2416 idaw_len = 0; 2452 idaw_len = 0;
2417 end_idaw = 0; 2453 end_idaw = 0;
2418 } 2454 }
@@ -3998,6 +4034,7 @@ static struct ccw_driver dasd_eckd_driver = {
3998 .thaw = dasd_generic_restore_device, 4034 .thaw = dasd_generic_restore_device,
3999 .restore = dasd_generic_restore_device, 4035 .restore = dasd_generic_restore_device,
4000 .uc_handler = dasd_generic_uc_handler, 4036 .uc_handler = dasd_generic_uc_handler,
4037 .int_class = IOINT_DAS,
4001}; 4038};
4002 4039
4003/* 4040/*
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 4b71b1164868..a62a75358eb9 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -79,6 +79,7 @@ static struct ccw_driver dasd_fba_driver = {
79 .freeze = dasd_generic_pm_freeze, 79 .freeze = dasd_generic_pm_freeze,
80 .thaw = dasd_generic_restore_device, 80 .thaw = dasd_generic_restore_device,
81 .restore = dasd_generic_restore_device, 81 .restore = dasd_generic_restore_device,
82 .int_class = IOINT_DAS,
82}; 83};
83 84
84static void 85static void
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 1dd12bd85a69..afe8c33422ed 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -516,6 +516,7 @@ struct dasd_block {
516 */ 516 */
517#define DASD_FLAG_IS_RESERVED 7 /* The device is reserved */ 517#define DASD_FLAG_IS_RESERVED 7 /* The device is reserved */
518#define DASD_FLAG_LOCK_STOLEN 8 /* The device lock was stolen */ 518#define DASD_FLAG_LOCK_STOLEN 8 /* The device lock was stolen */
519#define DASD_FLAG_SUSPENDED 9 /* The device was suspended */
519 520
520 521
521void dasd_put_device_wake(struct dasd_device *); 522void dasd_put_device_wake(struct dasd_device *);
@@ -643,6 +644,7 @@ struct dasd_ccw_req *
643dasd_smalloc_request(int , int, int, struct dasd_device *); 644dasd_smalloc_request(int , int, int, struct dasd_device *);
644void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *); 645void dasd_kfree_request(struct dasd_ccw_req *, struct dasd_device *);
645void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *); 646void dasd_sfree_request(struct dasd_ccw_req *, struct dasd_device *);
647void dasd_wakeup_cb(struct dasd_ccw_req *, void *);
646 648
647static inline int 649static inline int
648dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device) 650dasd_kmalloc_set_cda(struct ccw1 *ccw, void *cda, struct dasd_device *device)
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 694464c65fcd..934458ad55e5 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -9,7 +9,6 @@
9 * Dan Morrison, IBM Corporation <dmorriso@cse.buffalo.edu> 9 * Dan Morrison, IBM Corporation <dmorriso@cse.buffalo.edu>
10 */ 10 */
11 11
12#include <linux/kernel_stat.h>
13#include <linux/module.h> 12#include <linux/module.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/kdev_t.h> 14#include <linux/kdev_t.h>
@@ -362,7 +361,6 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
362 int cstat, dstat; 361 int cstat, dstat;
363 int count; 362 int count;
364 363
365 kstat_cpu(smp_processor_id()).irqs[IOINT_C15]++;
366 raw = dev_get_drvdata(&cdev->dev); 364 raw = dev_get_drvdata(&cdev->dev);
367 req = (struct raw3215_req *) intparm; 365 req = (struct raw3215_req *) intparm;
368 cstat = irb->scsw.cmd.cstat; 366 cstat = irb->scsw.cmd.cstat;
@@ -776,6 +774,7 @@ static struct ccw_driver raw3215_ccw_driver = {
776 .freeze = &raw3215_pm_stop, 774 .freeze = &raw3215_pm_stop,
777 .thaw = &raw3215_pm_start, 775 .thaw = &raw3215_pm_start,
778 .restore = &raw3215_pm_start, 776 .restore = &raw3215_pm_start,
777 .int_class = IOINT_C15,
779}; 778};
780 779
781#ifdef CONFIG_TN3215_CONSOLE 780#ifdef CONFIG_TN3215_CONSOLE
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 810ac38631c3..e5cb9248a442 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -7,7 +7,6 @@
7 * Copyright IBM Corp. 2003, 2009 7 * Copyright IBM Corp. 2003, 2009
8 */ 8 */
9 9
10#include <linux/kernel_stat.h>
11#include <linux/module.h> 10#include <linux/module.h>
12#include <linux/err.h> 11#include <linux/err.h>
13#include <linux/init.h> 12#include <linux/init.h>
@@ -330,7 +329,6 @@ raw3270_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
330 struct raw3270_request *rq; 329 struct raw3270_request *rq;
331 int rc; 330 int rc;
332 331
333 kstat_cpu(smp_processor_id()).irqs[IOINT_C70]++;
334 rp = dev_get_drvdata(&cdev->dev); 332 rp = dev_get_drvdata(&cdev->dev);
335 if (!rp) 333 if (!rp)
336 return; 334 return;
@@ -1398,6 +1396,7 @@ static struct ccw_driver raw3270_ccw_driver = {
1398 .freeze = &raw3270_pm_stop, 1396 .freeze = &raw3270_pm_stop,
1399 .thaw = &raw3270_pm_start, 1397 .thaw = &raw3270_pm_start,
1400 .restore = &raw3270_pm_start, 1398 .restore = &raw3270_pm_start,
1399 .int_class = IOINT_C70,
1401}; 1400};
1402 1401
1403static int 1402static int
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 837e010299a8..0b54a91f8dcd 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -61,8 +61,8 @@ static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb)
61 rc = sclp_service_call(cmd, sccb); 61 rc = sclp_service_call(cmd, sccb);
62 if (rc) 62 if (rc)
63 goto out; 63 goto out;
64 __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | 64 __load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA |
65 PSW_MASK_WAIT | PSW_DEFAULT_KEY); 65 PSW_MASK_BA | PSW_MASK_EXT | PSW_MASK_WAIT);
66 local_irq_disable(); 66 local_irq_disable();
67out: 67out:
68 /* Contents of the sccb might have changed. */ 68 /* Contents of the sccb might have changed. */
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
index a90a02c28d6a..87fc0ac11e67 100644
--- a/drivers/s390/char/sclp_quiesce.c
+++ b/drivers/s390/char/sclp_quiesce.c
@@ -30,7 +30,8 @@ static void do_machine_quiesce(void)
30 psw_t quiesce_psw; 30 psw_t quiesce_psw;
31 31
32 smp_send_stop(); 32 smp_send_stop();
33 quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; 33 quiesce_psw.mask =
34 PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA | PSW_MASK_WAIT;
34 quiesce_psw.addr = 0xfff; 35 quiesce_psw.addr = 0xfff;
35 __load_psw(quiesce_psw); 36 __load_psw(quiesce_psw);
36} 37}
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 9eff2df70ddb..934ef33eb9a4 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -1330,6 +1330,7 @@ static struct ccw_driver tape_34xx_driver = {
1330 .set_online = tape_34xx_online, 1330 .set_online = tape_34xx_online,
1331 .set_offline = tape_generic_offline, 1331 .set_offline = tape_generic_offline,
1332 .freeze = tape_generic_pm_suspend, 1332 .freeze = tape_generic_pm_suspend,
1333 .int_class = IOINT_TAP,
1333}; 1334};
1334 1335
1335static int 1336static int
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index a7d570728882..49c6aab7ad78 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -1762,6 +1762,7 @@ static struct ccw_driver tape_3590_driver = {
1762 .set_offline = tape_generic_offline, 1762 .set_offline = tape_generic_offline,
1763 .set_online = tape_3590_online, 1763 .set_online = tape_3590_online,
1764 .freeze = tape_generic_pm_suspend, 1764 .freeze = tape_generic_pm_suspend,
1765 .int_class = IOINT_TAP,
1765}; 1766};
1766 1767
1767/* 1768/*
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 7978a0adeaf3..b3a3e8e8656e 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -14,7 +14,6 @@
14#define KMSG_COMPONENT "tape" 14#define KMSG_COMPONENT "tape"
15#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 15#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
16 16
17#include <linux/kernel_stat.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/init.h> // for kernel parameters 18#include <linux/init.h> // for kernel parameters
20#include <linux/kmod.h> // for requesting modules 19#include <linux/kmod.h> // for requesting modules
@@ -1115,7 +1114,6 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1115 struct tape_request *request; 1114 struct tape_request *request;
1116 int rc; 1115 int rc;
1117 1116
1118 kstat_cpu(smp_processor_id()).irqs[IOINT_TAP]++;
1119 device = dev_get_drvdata(&cdev->dev); 1117 device = dev_get_drvdata(&cdev->dev);
1120 if (device == NULL) { 1118 if (device == NULL) {
1121 return; 1119 return;
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index f6b00c3df425..d291a54acfad 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -11,7 +11,6 @@
11#define KMSG_COMPONENT "vmur" 11#define KMSG_COMPONENT "vmur"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13 13
14#include <linux/kernel_stat.h>
15#include <linux/cdev.h> 14#include <linux/cdev.h>
16#include <linux/slab.h> 15#include <linux/slab.h>
17 16
@@ -74,6 +73,7 @@ static struct ccw_driver ur_driver = {
74 .set_online = ur_set_online, 73 .set_online = ur_set_online,
75 .set_offline = ur_set_offline, 74 .set_offline = ur_set_offline,
76 .freeze = ur_pm_suspend, 75 .freeze = ur_pm_suspend,
76 .int_class = IOINT_VMR,
77}; 77};
78 78
79static DEFINE_MUTEX(vmur_mutex); 79static DEFINE_MUTEX(vmur_mutex);
@@ -305,7 +305,6 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,
305{ 305{
306 struct urdev *urd; 306 struct urdev *urd;
307 307
308 kstat_cpu(smp_processor_id()).irqs[IOINT_VMR]++;
309 TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n", 308 TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n",
310 intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, 309 intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
311 irb->scsw.cmd.count); 310 irb->scsw.cmd.count);
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 3b94044027c2..43068fbd0baa 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -16,6 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/miscdevice.h> 17#include <linux/miscdevice.h>
18#include <linux/debugfs.h> 18#include <linux/debugfs.h>
19#include <linux/module.h>
19#include <asm/asm-offsets.h> 20#include <asm/asm-offsets.h>
20#include <asm/ipl.h> 21#include <asm/ipl.h>
21#include <asm/sclp.h> 22#include <asm/sclp.h>
@@ -142,22 +143,6 @@ static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
142 return memcpy_hsa(dest, src, count, TO_KERNEL); 143 return memcpy_hsa(dest, src, count, TO_KERNEL);
143} 144}
144 145
145static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
146{
147 static char buf[4096];
148 int offs = 0, size;
149
150 while (offs < count) {
151 size = min(sizeof(buf), count - offs);
152 if (memcpy_real(buf, (void *) src + offs, size))
153 return -EFAULT;
154 if (copy_to_user(dest + offs, buf, size))
155 return -EFAULT;
156 offs += size;
157 }
158 return 0;
159}
160
161static int __init init_cpu_info(enum arch_id arch) 146static int __init init_cpu_info(enum arch_id arch)
162{ 147{
163 struct save_area *sa; 148 struct save_area *sa;
@@ -346,8 +331,8 @@ static ssize_t zcore_read(struct file *file, char __user *buf, size_t count,
346 331
347 /* Copy from real mem */ 332 /* Copy from real mem */
348 size = count - mem_offs - hdr_count; 333 size = count - mem_offs - hdr_count;
349 rc = memcpy_real_user(buf + hdr_count + mem_offs, mem_start + mem_offs, 334 rc = copy_to_user_real(buf + hdr_count + mem_offs,
350 size); 335 (void *) mem_start + mem_offs, size);
351 if (rc) 336 if (rc)
352 goto fail; 337 goto fail;
353 338
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 5c567414c4bb..4f1989d27b1f 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -29,31 +29,20 @@
29 29
30/* a device matches a driver if all its slave devices match the same 30/* a device matches a driver if all its slave devices match the same
31 * entry of the driver */ 31 * entry of the driver */
32static int 32static int ccwgroup_bus_match(struct device *dev, struct device_driver * drv)
33ccwgroup_bus_match (struct device * dev, struct device_driver * drv)
34{ 33{
35 struct ccwgroup_device *gdev; 34 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
36 struct ccwgroup_driver *gdrv; 35 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(drv);
37
38 gdev = to_ccwgroupdev(dev);
39 gdrv = to_ccwgroupdrv(drv);
40 36
41 if (gdev->creator_id == gdrv->driver_id) 37 if (gdev->creator_id == gdrv->driver_id)
42 return 1; 38 return 1;
43 39
44 return 0; 40 return 0;
45} 41}
46static int
47ccwgroup_uevent (struct device *dev, struct kobj_uevent_env *env)
48{
49 /* TODO */
50 return 0;
51}
52 42
53static struct bus_type ccwgroup_bus_type; 43static struct bus_type ccwgroup_bus_type;
54 44
55static void 45static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
56__ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
57{ 46{
58 int i; 47 int i;
59 char str[8]; 48 char str[8];
@@ -63,7 +52,6 @@ __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
63 sysfs_remove_link(&gdev->dev.kobj, str); 52 sysfs_remove_link(&gdev->dev.kobj, str);
64 sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device"); 53 sysfs_remove_link(&gdev->cdev[i]->dev.kobj, "group_device");
65 } 54 }
66
67} 55}
68 56
69/* 57/*
@@ -87,6 +75,87 @@ static void __ccwgroup_remove_cdev_refs(struct ccwgroup_device *gdev)
87 } 75 }
88} 76}
89 77
78static int ccwgroup_set_online(struct ccwgroup_device *gdev)
79{
80 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
81 int ret = 0;
82
83 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
84 return -EAGAIN;
85 if (gdev->state == CCWGROUP_ONLINE)
86 goto out;
87 if (gdrv->set_online)
88 ret = gdrv->set_online(gdev);
89 if (ret)
90 goto out;
91
92 gdev->state = CCWGROUP_ONLINE;
93out:
94 atomic_set(&gdev->onoff, 0);
95 return ret;
96}
97
98static int ccwgroup_set_offline(struct ccwgroup_device *gdev)
99{
100 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
101 int ret = 0;
102
103 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
104 return -EAGAIN;
105 if (gdev->state == CCWGROUP_OFFLINE)
106 goto out;
107 if (gdrv->set_offline)
108 ret = gdrv->set_offline(gdev);
109 if (ret)
110 goto out;
111
112 gdev->state = CCWGROUP_OFFLINE;
113out:
114 atomic_set(&gdev->onoff, 0);
115 return ret;
116}
117
118static ssize_t ccwgroup_online_store(struct device *dev,
119 struct device_attribute *attr,
120 const char *buf, size_t count)
121{
122 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
123 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
124 unsigned long value;
125 int ret;
126
127 if (!dev->driver)
128 return -EINVAL;
129 if (!try_module_get(gdrv->driver.owner))
130 return -EINVAL;
131
132 ret = strict_strtoul(buf, 0, &value);
133 if (ret)
134 goto out;
135
136 if (value == 1)
137 ret = ccwgroup_set_online(gdev);
138 else if (value == 0)
139 ret = ccwgroup_set_offline(gdev);
140 else
141 ret = -EINVAL;
142out:
143 module_put(gdrv->driver.owner);
144 return (ret == 0) ? count : ret;
145}
146
147static ssize_t ccwgroup_online_show(struct device *dev,
148 struct device_attribute *attr,
149 char *buf)
150{
151 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
152 int online;
153
154 online = (gdev->state == CCWGROUP_ONLINE) ? 1 : 0;
155
156 return scnprintf(buf, PAGE_SIZE, "%d\n", online);
157}
158
90/* 159/*
91 * Provide an 'ungroup' attribute so the user can remove group devices no 160 * Provide an 'ungroup' attribute so the user can remove group devices no
92 * longer needed or accidentially created. Saves memory :) 161 * longer needed or accidentially created. Saves memory :)
@@ -104,14 +173,13 @@ static void ccwgroup_ungroup_callback(struct device *dev)
104 mutex_unlock(&gdev->reg_mutex); 173 mutex_unlock(&gdev->reg_mutex);
105} 174}
106 175
107static ssize_t 176static ssize_t ccwgroup_ungroup_store(struct device *dev,
108ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 177 struct device_attribute *attr,
178 const char *buf, size_t count)
109{ 179{
110 struct ccwgroup_device *gdev; 180 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
111 int rc; 181 int rc;
112 182
113 gdev = to_ccwgroupdev(dev);
114
115 /* Prevent concurrent online/offline processing and ungrouping. */ 183 /* Prevent concurrent online/offline processing and ungrouping. */
116 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) 184 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
117 return -EAGAIN; 185 return -EAGAIN;
@@ -132,24 +200,35 @@ out:
132 } 200 }
133 return count; 201 return count;
134} 202}
135
136static DEVICE_ATTR(ungroup, 0200, NULL, ccwgroup_ungroup_store); 203static DEVICE_ATTR(ungroup, 0200, NULL, ccwgroup_ungroup_store);
204static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store);
137 205
138static void 206static struct attribute *ccwgroup_attrs[] = {
139ccwgroup_release (struct device *dev) 207 &dev_attr_online.attr,
208 &dev_attr_ungroup.attr,
209 NULL,
210};
211static struct attribute_group ccwgroup_attr_group = {
212 .attrs = ccwgroup_attrs,
213};
214static const struct attribute_group *ccwgroup_attr_groups[] = {
215 &ccwgroup_attr_group,
216 NULL,
217};
218
219static void ccwgroup_release(struct device *dev)
140{ 220{
141 kfree(to_ccwgroupdev(dev)); 221 kfree(to_ccwgroupdev(dev));
142} 222}
143 223
144static int 224static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
145__ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
146{ 225{
147 char str[8]; 226 char str[8];
148 int i, rc; 227 int i, rc;
149 228
150 for (i = 0; i < gdev->count; i++) { 229 for (i = 0; i < gdev->count; i++) {
151 rc = sysfs_create_link(&gdev->cdev[i]->dev.kobj, &gdev->dev.kobj, 230 rc = sysfs_create_link(&gdev->cdev[i]->dev.kobj,
152 "group_device"); 231 &gdev->dev.kobj, "group_device");
153 if (rc) { 232 if (rc) {
154 for (--i; i >= 0; i--) 233 for (--i; i >= 0; i--)
155 sysfs_remove_link(&gdev->cdev[i]->dev.kobj, 234 sysfs_remove_link(&gdev->cdev[i]->dev.kobj,
@@ -159,8 +238,8 @@ __ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
159 } 238 }
160 for (i = 0; i < gdev->count; i++) { 239 for (i = 0; i < gdev->count; i++) {
161 sprintf(str, "cdev%d", i); 240 sprintf(str, "cdev%d", i);
162 rc = sysfs_create_link(&gdev->dev.kobj, &gdev->cdev[i]->dev.kobj, 241 rc = sysfs_create_link(&gdev->dev.kobj,
163 str); 242 &gdev->cdev[i]->dev.kobj, str);
164 if (rc) { 243 if (rc) {
165 for (--i; i >= 0; i--) { 244 for (--i; i >= 0; i--) {
166 sprintf(str, "cdev%d", i); 245 sprintf(str, "cdev%d", i);
@@ -293,26 +372,17 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
293 } 372 }
294 373
295 dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); 374 dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
296 375 gdev->dev.groups = ccwgroup_attr_groups;
297 rc = device_add(&gdev->dev); 376 rc = device_add(&gdev->dev);
298 if (rc) 377 if (rc)
299 goto error; 378 goto error;
300 get_device(&gdev->dev); 379 rc = __ccwgroup_create_symlinks(gdev);
301 rc = device_create_file(&gdev->dev, &dev_attr_ungroup);
302
303 if (rc) { 380 if (rc) {
304 device_unregister(&gdev->dev); 381 device_del(&gdev->dev);
305 goto error; 382 goto error;
306 } 383 }
307 384 mutex_unlock(&gdev->reg_mutex);
308 rc = __ccwgroup_create_symlinks(gdev); 385 return 0;
309 if (!rc) {
310 mutex_unlock(&gdev->reg_mutex);
311 put_device(&gdev->dev);
312 return 0;
313 }
314 device_remove_file(&gdev->dev, &dev_attr_ungroup);
315 device_unregister(&gdev->dev);
316error: 386error:
317 for (i = 0; i < num_devices; i++) 387 for (i = 0; i < num_devices; i++)
318 if (gdev->cdev[i]) { 388 if (gdev->cdev[i]) {
@@ -330,7 +400,15 @@ error:
330EXPORT_SYMBOL(ccwgroup_create_from_string); 400EXPORT_SYMBOL(ccwgroup_create_from_string);
331 401
332static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, 402static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
333 void *data); 403 void *data)
404{
405 struct device *dev = data;
406
407 if (action == BUS_NOTIFY_UNBIND_DRIVER)
408 device_schedule_callback(dev, ccwgroup_ungroup_callback);
409
410 return NOTIFY_OK;
411}
334 412
335static struct notifier_block ccwgroup_nb = { 413static struct notifier_block ccwgroup_nb = {
336 .notifier_call = ccwgroup_notifier 414 .notifier_call = ccwgroup_notifier
@@ -362,138 +440,21 @@ module_exit(cleanup_ccwgroup);
362 440
363/************************** driver stuff ******************************/ 441/************************** driver stuff ******************************/
364 442
365static int 443static int ccwgroup_probe(struct device *dev)
366ccwgroup_set_online(struct ccwgroup_device *gdev)
367{ 444{
368 struct ccwgroup_driver *gdrv; 445 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
369 int ret; 446 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
370
371 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
372 return -EAGAIN;
373 if (gdev->state == CCWGROUP_ONLINE) {
374 ret = 0;
375 goto out;
376 }
377 if (!gdev->dev.driver) {
378 ret = -EINVAL;
379 goto out;
380 }
381 gdrv = to_ccwgroupdrv (gdev->dev.driver);
382 if ((ret = gdrv->set_online ? gdrv->set_online(gdev) : 0))
383 goto out;
384
385 gdev->state = CCWGROUP_ONLINE;
386 out:
387 atomic_set(&gdev->onoff, 0);
388 return ret;
389}
390
391static int
392ccwgroup_set_offline(struct ccwgroup_device *gdev)
393{
394 struct ccwgroup_driver *gdrv;
395 int ret;
396
397 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
398 return -EAGAIN;
399 if (gdev->state == CCWGROUP_OFFLINE) {
400 ret = 0;
401 goto out;
402 }
403 if (!gdev->dev.driver) {
404 ret = -EINVAL;
405 goto out;
406 }
407 gdrv = to_ccwgroupdrv (gdev->dev.driver);
408 if ((ret = gdrv->set_offline ? gdrv->set_offline(gdev) : 0))
409 goto out;
410
411 gdev->state = CCWGROUP_OFFLINE;
412 out:
413 atomic_set(&gdev->onoff, 0);
414 return ret;
415}
416
417static ssize_t
418ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
419{
420 struct ccwgroup_device *gdev;
421 struct ccwgroup_driver *gdrv;
422 unsigned long value;
423 int ret;
424
425 if (!dev->driver)
426 return -ENODEV;
427
428 gdev = to_ccwgroupdev(dev);
429 gdrv = to_ccwgroupdrv(dev->driver);
430
431 if (!try_module_get(gdrv->driver.owner))
432 return -EINVAL;
433
434 ret = strict_strtoul(buf, 0, &value);
435 if (ret)
436 goto out;
437
438 if (value == 1)
439 ret = ccwgroup_set_online(gdev);
440 else if (value == 0)
441 ret = ccwgroup_set_offline(gdev);
442 else
443 ret = -EINVAL;
444out:
445 module_put(gdrv->driver.owner);
446 return (ret == 0) ? count : ret;
447}
448
449static ssize_t
450ccwgroup_online_show (struct device *dev, struct device_attribute *attr, char *buf)
451{
452 int online;
453
454 online = (to_ccwgroupdev(dev)->state == CCWGROUP_ONLINE);
455
456 return sprintf(buf, online ? "1\n" : "0\n");
457}
458
459static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store);
460
461static int
462ccwgroup_probe (struct device *dev)
463{
464 struct ccwgroup_device *gdev;
465 struct ccwgroup_driver *gdrv;
466
467 int ret;
468
469 gdev = to_ccwgroupdev(dev);
470 gdrv = to_ccwgroupdrv(dev->driver);
471
472 if ((ret = device_create_file(dev, &dev_attr_online)))
473 return ret;
474
475 ret = gdrv->probe ? gdrv->probe(gdev) : -ENODEV;
476 if (ret)
477 device_remove_file(dev, &dev_attr_online);
478 447
479 return ret; 448 return gdrv->probe ? gdrv->probe(gdev) : -ENODEV;
480} 449}
481 450
482static int 451static int ccwgroup_remove(struct device *dev)
483ccwgroup_remove (struct device *dev)
484{ 452{
485 struct ccwgroup_device *gdev; 453 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
486 struct ccwgroup_driver *gdrv; 454 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
487
488 device_remove_file(dev, &dev_attr_online);
489 device_remove_file(dev, &dev_attr_ungroup);
490 455
491 if (!dev->driver) 456 if (!dev->driver)
492 return 0; 457 return 0;
493
494 gdev = to_ccwgroupdev(dev);
495 gdrv = to_ccwgroupdrv(dev->driver);
496
497 if (gdrv->remove) 458 if (gdrv->remove)
498 gdrv->remove(gdev); 459 gdrv->remove(gdev);
499 460
@@ -502,15 +463,11 @@ ccwgroup_remove (struct device *dev)
502 463
503static void ccwgroup_shutdown(struct device *dev) 464static void ccwgroup_shutdown(struct device *dev)
504{ 465{
505 struct ccwgroup_device *gdev; 466 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
506 struct ccwgroup_driver *gdrv; 467 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
507 468
508 if (!dev->driver) 469 if (!dev->driver)
509 return; 470 return;
510
511 gdev = to_ccwgroupdev(dev);
512 gdrv = to_ccwgroupdrv(dev->driver);
513
514 if (gdrv->shutdown) 471 if (gdrv->shutdown)
515 gdrv->shutdown(gdev); 472 gdrv->shutdown(gdev);
516} 473}
@@ -586,26 +543,12 @@ static const struct dev_pm_ops ccwgroup_pm_ops = {
586static struct bus_type ccwgroup_bus_type = { 543static struct bus_type ccwgroup_bus_type = {
587 .name = "ccwgroup", 544 .name = "ccwgroup",
588 .match = ccwgroup_bus_match, 545 .match = ccwgroup_bus_match,
589 .uevent = ccwgroup_uevent,
590 .probe = ccwgroup_probe, 546 .probe = ccwgroup_probe,
591 .remove = ccwgroup_remove, 547 .remove = ccwgroup_remove,
592 .shutdown = ccwgroup_shutdown, 548 .shutdown = ccwgroup_shutdown,
593 .pm = &ccwgroup_pm_ops, 549 .pm = &ccwgroup_pm_ops,
594}; 550};
595 551
596
597static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
598 void *data)
599{
600 struct device *dev = data;
601
602 if (action == BUS_NOTIFY_UNBIND_DRIVER)
603 device_schedule_callback(dev, ccwgroup_ungroup_callback);
604
605 return NOTIFY_OK;
606}
607
608
609/** 552/**
610 * ccwgroup_driver_register() - register a ccw group driver 553 * ccwgroup_driver_register() - register a ccw group driver
611 * @cdriver: driver to be registered 554 * @cdriver: driver to be registered
@@ -619,9 +562,9 @@ int ccwgroup_driver_register(struct ccwgroup_driver *cdriver)
619 562
620 return driver_register(&cdriver->driver); 563 return driver_register(&cdriver->driver);
621} 564}
565EXPORT_SYMBOL(ccwgroup_driver_register);
622 566
623static int 567static int __ccwgroup_match_all(struct device *dev, void *data)
624__ccwgroup_match_all(struct device *dev, void *data)
625{ 568{
626 return 1; 569 return 1;
627} 570}
@@ -652,6 +595,7 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
652 put_driver(&cdriver->driver); 595 put_driver(&cdriver->driver);
653 driver_unregister(&cdriver->driver); 596 driver_unregister(&cdriver->driver);
654} 597}
598EXPORT_SYMBOL(ccwgroup_driver_unregister);
655 599
656/** 600/**
657 * ccwgroup_probe_ccwdev() - probe function for slave devices 601 * ccwgroup_probe_ccwdev() - probe function for slave devices
@@ -666,6 +610,7 @@ int ccwgroup_probe_ccwdev(struct ccw_device *cdev)
666{ 610{
667 return 0; 611 return 0;
668} 612}
613EXPORT_SYMBOL(ccwgroup_probe_ccwdev);
669 614
670/** 615/**
671 * ccwgroup_remove_ccwdev() - remove function for slave devices 616 * ccwgroup_remove_ccwdev() - remove function for slave devices
@@ -702,9 +647,5 @@ void ccwgroup_remove_ccwdev(struct ccw_device *cdev)
702 /* Release ccwgroup device reference for local processing. */ 647 /* Release ccwgroup device reference for local processing. */
703 put_device(&gdev->dev); 648 put_device(&gdev->dev);
704} 649}
705
706MODULE_LICENSE("GPL");
707EXPORT_SYMBOL(ccwgroup_driver_register);
708EXPORT_SYMBOL(ccwgroup_driver_unregister);
709EXPORT_SYMBOL(ccwgroup_probe_ccwdev);
710EXPORT_SYMBOL(ccwgroup_remove_ccwdev); 650EXPORT_SYMBOL(ccwgroup_remove_ccwdev);
651MODULE_LICENSE("GPL");
diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c
index d15f8b4d78bd..5156264d0c74 100644
--- a/drivers/s390/cio/ccwreq.c
+++ b/drivers/s390/cio/ccwreq.c
@@ -1,10 +1,13 @@
1/* 1/*
2 * Handling of internal CCW device requests. 2 * Handling of internal CCW device requests.
3 * 3 *
4 * Copyright IBM Corp. 2009 4 * Copyright IBM Corp. 2009, 2011
5 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 5 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6 */ 6 */
7 7
8#define KMSG_COMPONENT "cio"
9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
10
8#include <linux/types.h> 11#include <linux/types.h>
9#include <linux/err.h> 12#include <linux/err.h>
10#include <asm/ccwdev.h> 13#include <asm/ccwdev.h>
@@ -323,7 +326,21 @@ void ccw_request_timeout(struct ccw_device *cdev)
323{ 326{
324 struct subchannel *sch = to_subchannel(cdev->dev.parent); 327 struct subchannel *sch = to_subchannel(cdev->dev.parent);
325 struct ccw_request *req = &cdev->private->req; 328 struct ccw_request *req = &cdev->private->req;
326 int rc; 329 int rc = -ENODEV, chp;
330
331 if (cio_update_schib(sch))
332 goto err;
333
334 for (chp = 0; chp < 8; chp++) {
335 if ((0x80 >> chp) & sch->schib.pmcw.lpum)
336 pr_warning("%s: No interrupt was received within %lus "
337 "(CS=%02x, DS=%02x, CHPID=%x.%02x)\n",
338 dev_name(&cdev->dev), req->timeout / HZ,
339 scsw_cstat(&sch->schib.scsw),
340 scsw_dstat(&sch->schib.scsw),
341 sch->schid.cssid,
342 sch->schib.pmcw.chpid[chp]);
343 }
327 344
328 if (!ccwreq_next_path(cdev)) { 345 if (!ccwreq_next_path(cdev)) {
329 /* set the final return code for this request */ 346 /* set the final return code for this request */
@@ -342,7 +359,7 @@ err:
342 * ccw_request_notoper - notoper handler for I/O request procedure 359 * ccw_request_notoper - notoper handler for I/O request procedure
343 * @cdev: ccw device 360 * @cdev: ccw device
344 * 361 *
345 * Handle timeout during I/O request procedure. 362 * Handle notoper during I/O request procedure.
346 */ 363 */
347void ccw_request_notoper(struct ccw_device *cdev) 364void ccw_request_notoper(struct ccw_device *cdev)
348{ 365{
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index e950f1ad4dd1..0c87b0fc7714 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for s390 chsc subchannels 2 * Driver for s390 chsc subchannels
3 * 3 *
4 * Copyright IBM Corp. 2008, 2009 4 * Copyright IBM Corp. 2008, 2011
5 * 5 *
6 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> 6 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
7 * 7 *
@@ -12,6 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/uaccess.h> 13#include <linux/uaccess.h>
14#include <linux/miscdevice.h> 14#include <linux/miscdevice.h>
15#include <linux/kernel_stat.h>
15 16
16#include <asm/compat.h> 17#include <asm/compat.h>
17#include <asm/cio.h> 18#include <asm/cio.h>
@@ -56,6 +57,8 @@ static void chsc_subchannel_irq(struct subchannel *sch)
56 57
57 CHSC_LOG(4, "irb"); 58 CHSC_LOG(4, "irb");
58 CHSC_LOG_HEX(4, irb, sizeof(*irb)); 59 CHSC_LOG_HEX(4, irb, sizeof(*irb));
60 kstat_cpu(smp_processor_id()).irqs[IOINT_CSC]++;
61
59 /* Copy irb to provided request and set done. */ 62 /* Copy irb to provided request and set done. */
60 if (!request) { 63 if (!request) {
61 CHSC_MSG(0, "Interrupt on sch 0.%x.%04x with no request\n", 64 CHSC_MSG(0, "Interrupt on sch 0.%x.%04x with no request\n",
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index eb3140ee821e..dc67c397449e 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -622,6 +622,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
622 sch = (struct subchannel *)(unsigned long)tpi_info->intparm; 622 sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
623 if (!sch) { 623 if (!sch) {
624 /* Clear pending interrupt condition. */ 624 /* Clear pending interrupt condition. */
625 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
625 tsch(tpi_info->schid, irb); 626 tsch(tpi_info->schid, irb);
626 continue; 627 continue;
627 } 628 }
@@ -634,7 +635,10 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
634 /* Call interrupt handler if there is one. */ 635 /* Call interrupt handler if there is one. */
635 if (sch->driver && sch->driver->irq) 636 if (sch->driver && sch->driver->irq)
636 sch->driver->irq(sch); 637 sch->driver->irq(sch);
637 } 638 else
639 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
640 } else
641 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
638 spin_unlock(sch->lock); 642 spin_unlock(sch->lock);
639 /* 643 /*
640 * Are more interrupts pending? 644 * Are more interrupts pending?
@@ -667,18 +671,23 @@ static int cio_tpi(void)
667 tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id; 671 tpi_info = (struct tpi_info *)&S390_lowcore.subchannel_id;
668 if (tpi(NULL) != 1) 672 if (tpi(NULL) != 1)
669 return 0; 673 return 0;
674 kstat_cpu(smp_processor_id()).irqs[IO_INTERRUPT]++;
670 if (tpi_info->adapter_IO) { 675 if (tpi_info->adapter_IO) {
671 do_adapter_IO(tpi_info->isc); 676 do_adapter_IO(tpi_info->isc);
672 return 1; 677 return 1;
673 } 678 }
674 irb = (struct irb *)&S390_lowcore.irb; 679 irb = (struct irb *)&S390_lowcore.irb;
675 /* Store interrupt response block to lowcore. */ 680 /* Store interrupt response block to lowcore. */
676 if (tsch(tpi_info->schid, irb) != 0) 681 if (tsch(tpi_info->schid, irb) != 0) {
677 /* Not status pending or not operational. */ 682 /* Not status pending or not operational. */
683 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
678 return 1; 684 return 1;
685 }
679 sch = (struct subchannel *)(unsigned long)tpi_info->intparm; 686 sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
680 if (!sch) 687 if (!sch) {
688 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
681 return 1; 689 return 1;
690 }
682 irq_context = in_interrupt(); 691 irq_context = in_interrupt();
683 if (!irq_context) 692 if (!irq_context)
684 local_bh_disable(); 693 local_bh_disable();
@@ -687,6 +696,8 @@ static int cio_tpi(void)
687 memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw)); 696 memcpy(&sch->schib.scsw, &irb->scsw, sizeof(union scsw));
688 if (sch->driver && sch->driver->irq) 697 if (sch->driver && sch->driver->irq)
689 sch->driver->irq(sch); 698 sch->driver->irq(sch);
699 else
700 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
690 spin_unlock(sch->lock); 701 spin_unlock(sch->lock);
691 irq_exit(); 702 irq_exit();
692 if (!irq_context) 703 if (!irq_context)
@@ -1058,7 +1069,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
1058{ 1069{
1059 struct subchannel_id schid; 1070 struct subchannel_id schid;
1060 1071
1061 s390_reset_system(); 1072 s390_reset_system(NULL, NULL);
1062 if (reipl_find_schid(devid, &schid) != 0) 1073 if (reipl_find_schid(devid, &schid) != 0)
1063 panic("IPL Device not found\n"); 1074 panic("IPL Device not found\n");
1064 do_reipl_asm(*((__u32*)&schid)); 1075 do_reipl_asm(*((__u32*)&schid));
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 80ebdddf7747..33bb4d891e16 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -133,6 +133,8 @@ struct channel_subsystem {
133 133
134extern struct channel_subsystem *channel_subsystems[]; 134extern struct channel_subsystem *channel_subsystems[];
135 135
136void channel_subsystem_reinit(void);
137
136/* Helper functions to build lists for the slow path. */ 138/* Helper functions to build lists for the slow path. */
137void css_schedule_eval(struct subchannel_id schid); 139void css_schedule_eval(struct subchannel_id schid);
138void css_schedule_eval_all(void); 140void css_schedule_eval_all(void);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 8e04c00cf0ad..d734f4a0ecac 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -21,6 +21,7 @@
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/workqueue.h> 22#include <linux/workqueue.h>
23#include <linux/timer.h> 23#include <linux/timer.h>
24#include <linux/kernel_stat.h>
24 25
25#include <asm/ccwdev.h> 26#include <asm/ccwdev.h>
26#include <asm/cio.h> 27#include <asm/cio.h>
@@ -747,6 +748,7 @@ static int io_subchannel_initialize_dev(struct subchannel *sch,
747 struct ccw_device *cdev) 748 struct ccw_device *cdev)
748{ 749{
749 cdev->private->cdev = cdev; 750 cdev->private->cdev = cdev;
751 cdev->private->int_class = IOINT_CIO;
750 atomic_set(&cdev->private->onoff, 0); 752 atomic_set(&cdev->private->onoff, 0);
751 cdev->dev.parent = &sch->dev; 753 cdev->dev.parent = &sch->dev;
752 cdev->dev.release = ccw_device_release; 754 cdev->dev.release = ccw_device_release;
@@ -1010,6 +1012,8 @@ static void io_subchannel_irq(struct subchannel *sch)
1010 CIO_TRACE_EVENT(6, dev_name(&sch->dev)); 1012 CIO_TRACE_EVENT(6, dev_name(&sch->dev));
1011 if (cdev) 1013 if (cdev)
1012 dev_fsm_event(cdev, DEV_EVENT_INTERRUPT); 1014 dev_fsm_event(cdev, DEV_EVENT_INTERRUPT);
1015 else
1016 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
1013} 1017}
1014 1018
1015void io_subchannel_init_config(struct subchannel *sch) 1019void io_subchannel_init_config(struct subchannel *sch)
@@ -1621,6 +1625,7 @@ ccw_device_probe_console(void)
1621 memset(&console_private, 0, sizeof(struct ccw_device_private)); 1625 memset(&console_private, 0, sizeof(struct ccw_device_private));
1622 console_cdev.private = &console_private; 1626 console_cdev.private = &console_private;
1623 console_private.cdev = &console_cdev; 1627 console_private.cdev = &console_cdev;
1628 console_private.int_class = IOINT_CIO;
1624 ret = ccw_device_console_enable(&console_cdev, sch); 1629 ret = ccw_device_console_enable(&console_cdev, sch);
1625 if (ret) { 1630 if (ret) {
1626 cio_release_console(); 1631 cio_release_console();
@@ -1702,11 +1707,18 @@ ccw_device_probe (struct device *dev)
1702 int ret; 1707 int ret;
1703 1708
1704 cdev->drv = cdrv; /* to let the driver call _set_online */ 1709 cdev->drv = cdrv; /* to let the driver call _set_online */
1710 /* Note: we interpret class 0 in this context as an uninitialized
1711 * field since it translates to a non-I/O interrupt class. */
1712 if (cdrv->int_class != 0)
1713 cdev->private->int_class = cdrv->int_class;
1714 else
1715 cdev->private->int_class = IOINT_CIO;
1705 1716
1706 ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV; 1717 ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV;
1707 1718
1708 if (ret) { 1719 if (ret) {
1709 cdev->drv = NULL; 1720 cdev->drv = NULL;
1721 cdev->private->int_class = IOINT_CIO;
1710 return ret; 1722 return ret;
1711 } 1723 }
1712 1724
@@ -1740,6 +1752,7 @@ ccw_device_remove (struct device *dev)
1740 } 1752 }
1741 ccw_device_set_timeout(cdev, 0); 1753 ccw_device_set_timeout(cdev, 0);
1742 cdev->drv = NULL; 1754 cdev->drv = NULL;
1755 cdev->private->int_class = IOINT_CIO;
1743 return 0; 1756 return 0;
1744} 1757}
1745 1758
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 0b7245c72d5e..179824b3082f 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -5,6 +5,7 @@
5#include <linux/atomic.h> 5#include <linux/atomic.h>
6#include <linux/wait.h> 6#include <linux/wait.h>
7#include <linux/notifier.h> 7#include <linux/notifier.h>
8#include <linux/kernel_stat.h>
8#include "io_sch.h" 9#include "io_sch.h"
9 10
10/* 11/*
@@ -56,7 +57,17 @@ extern fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS];
56static inline void 57static inline void
57dev_fsm_event(struct ccw_device *cdev, enum dev_event dev_event) 58dev_fsm_event(struct ccw_device *cdev, enum dev_event dev_event)
58{ 59{
59 dev_jumptable[cdev->private->state][dev_event](cdev, dev_event); 60 int state = cdev->private->state;
61
62 if (dev_event == DEV_EVENT_INTERRUPT) {
63 if (state == DEV_STATE_ONLINE)
64 kstat_cpu(smp_processor_id()).
65 irqs[cdev->private->int_class]++;
66 else if (state != DEV_STATE_CMFCHANGE &&
67 state != DEV_STATE_CMFUPDATE)
68 kstat_cpu(smp_processor_id()).irqs[IOINT_CIO]++;
69 }
70 dev_jumptable[state][dev_event](cdev, dev_event);
60} 71}
61 72
62/* 73/*
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index ba31ad88f4f7..2ebb492a5c17 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -4,6 +4,7 @@
4#include <linux/types.h> 4#include <linux/types.h>
5#include <asm/schid.h> 5#include <asm/schid.h>
6#include <asm/ccwdev.h> 6#include <asm/ccwdev.h>
7#include <asm/irq.h>
7#include "css.h" 8#include "css.h"
8#include "orb.h" 9#include "orb.h"
9 10
@@ -157,6 +158,7 @@ struct ccw_device_private {
157 struct list_head cmb_list; /* list of measured devices */ 158 struct list_head cmb_list; /* list of measured devices */
158 u64 cmb_start_time; /* clock value of cmb reset */ 159 u64 cmb_start_time; /* clock value of cmb reset */
159 void *cmb_wait; /* deferred cmb enable/disable */ 160 void *cmb_wait; /* deferred cmb enable/disable */
161 enum interruption_class int_class;
160}; 162};
161 163
162static inline int rsch(struct subchannel_id schid) 164static inline int rsch(struct subchannel_id schid)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 3dd86441da3d..b962ffbc0803 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -18,14 +18,6 @@
18#define QDIO_BUSY_BIT_RETRIES 1000 /* = 10s retry time */ 18#define QDIO_BUSY_BIT_RETRIES 1000 /* = 10s retry time */
19#define QDIO_INPUT_THRESHOLD (500 << 12) /* 500 microseconds */ 19#define QDIO_INPUT_THRESHOLD (500 << 12) /* 500 microseconds */
20 20
21/*
22 * if an asynchronous HiperSockets queue runs full, the 10 seconds timer wait
23 * till next initiative to give transmitted skbs back to the stack is too long.
24 * Therefore polling is started in case of multicast queue is filled more
25 * than 50 percent.
26 */
27#define QDIO_IQDIO_POLL_LVL 65 /* HS multicast queue */
28
29enum qdio_irq_states { 21enum qdio_irq_states {
30 QDIO_IRQ_STATE_INACTIVE, 22 QDIO_IRQ_STATE_INACTIVE,
31 QDIO_IRQ_STATE_ESTABLISHED, 23 QDIO_IRQ_STATE_ESTABLISHED,
@@ -290,6 +282,9 @@ struct qdio_q {
290 /* error condition during a data transfer */ 282 /* error condition during a data transfer */
291 unsigned int qdio_error; 283 unsigned int qdio_error;
292 284
285 /* last scan of the queue */
286 u64 timestamp;
287
293 struct tasklet_struct tasklet; 288 struct tasklet_struct tasklet;
294 struct qdio_queue_perf_stat q_stats; 289 struct qdio_queue_perf_stat q_stats;
295 290
@@ -423,31 +418,7 @@ static inline int multicast_outbound(struct qdio_q *q)
423#define queue_irqs_disabled(q) \ 418#define queue_irqs_disabled(q) \
424 (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0) 419 (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0)
425 420
426#define TIQDIO_SHARED_IND 63 421extern u64 last_ai_time;
427
428/* device state change indicators */
429struct indicator_t {
430 u32 ind; /* u32 because of compare-and-swap performance */
431 atomic_t count; /* use count, 0 or 1 for non-shared indicators */
432};
433
434extern struct indicator_t *q_indicators;
435
436static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq)
437{
438 return irq->nr_input_qs > 1;
439}
440
441static inline int references_shared_dsci(struct qdio_irq *irq)
442{
443 return irq->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
444}
445
446static inline int shared_ind(struct qdio_q *q)
447{
448 struct qdio_irq *i = q->irq_ptr;
449 return references_shared_dsci(i) || has_multiple_inq_on_dsci(i);
450}
451 422
452/* prototypes for thin interrupt */ 423/* prototypes for thin interrupt */
453void qdio_setup_thinint(struct qdio_irq *irq_ptr); 424void qdio_setup_thinint(struct qdio_irq *irq_ptr);
@@ -460,7 +431,8 @@ int tiqdio_allocate_memory(void);
460void tiqdio_free_memory(void); 431void tiqdio_free_memory(void);
461int tiqdio_register_thinints(void); 432int tiqdio_register_thinints(void);
462void tiqdio_unregister_thinints(void); 433void tiqdio_unregister_thinints(void);
463 434void clear_nonshared_ind(struct qdio_irq *);
435int test_nonshared_ind(struct qdio_irq *);
464 436
465/* prototypes for setup */ 437/* prototypes for setup */
466void qdio_inbound_processing(unsigned long data); 438void qdio_inbound_processing(unsigned long data);
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index aaf7f935bfd3..ed68245f9741 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -54,15 +54,17 @@ static int qstat_show(struct seq_file *m, void *v)
54 if (!q) 54 if (!q)
55 return 0; 55 return 0;
56 56
57 seq_printf(m, "DSCI: %d nr_used: %d\n", 57 seq_printf(m, "Timestamp: %Lx Last AI: %Lx\n",
58 *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used)); 58 q->timestamp, last_ai_time);
59 seq_printf(m, "ftc: %d last_move: %d\n", 59 seq_printf(m, "nr_used: %d ftc: %d last_move: %d\n",
60 atomic_read(&q->nr_buf_used),
60 q->first_to_check, q->last_move); 61 q->first_to_check, q->last_move);
61 if (q->is_input_q) { 62 if (q->is_input_q) {
62 seq_printf(m, "polling: %d ack start: %d ack count: %d\n", 63 seq_printf(m, "polling: %d ack start: %d ack count: %d\n",
63 q->u.in.polling, q->u.in.ack_start, 64 q->u.in.polling, q->u.in.ack_start,
64 q->u.in.ack_count); 65 q->u.in.ack_count);
65 seq_printf(m, "IRQs disabled: %u\n", 66 seq_printf(m, "DSCI: %d IRQs disabled: %u\n",
67 *(u32 *)q->irq_ptr->dsci,
66 test_bit(QDIO_QUEUE_IRQS_DISABLED, 68 test_bit(QDIO_QUEUE_IRQS_DISABLED,
67 &q->u.in.queue_irq_state)); 69 &q->u.in.queue_irq_state));
68 } 70 }
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 6547ff469410..3ef8d071c64a 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -15,7 +15,6 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/gfp.h> 16#include <linux/gfp.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/kernel_stat.h>
19#include <linux/atomic.h> 18#include <linux/atomic.h>
20#include <asm/debug.h> 19#include <asm/debug.h>
21#include <asm/qdio.h> 20#include <asm/qdio.h>
@@ -105,9 +104,12 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
105 /* all done or next buffer state different */ 104 /* all done or next buffer state different */
106 if (ccq == 0 || ccq == 32) 105 if (ccq == 0 || ccq == 32)
107 return 0; 106 return 0;
108 /* not all buffers processed */ 107 /* no buffer processed */
109 if (ccq == 96 || ccq == 97) 108 if (ccq == 97)
110 return 1; 109 return 1;
110 /* not all buffers processed */
111 if (ccq == 96)
112 return 2;
111 /* notify devices immediately */ 113 /* notify devices immediately */
112 DBF_ERROR("%4x ccq:%3d", SCH_NO(q), ccq); 114 DBF_ERROR("%4x ccq:%3d", SCH_NO(q), ccq);
113 return -EIO; 115 return -EIO;
@@ -127,10 +129,8 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
127static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, 129static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
128 int start, int count, int auto_ack) 130 int start, int count, int auto_ack)
129{ 131{
132 int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0;
130 unsigned int ccq = 0; 133 unsigned int ccq = 0;
131 int tmp_count = count, tmp_start = start;
132 int nr = q->nr;
133 int rc;
134 134
135 BUG_ON(!q->irq_ptr->sch_token); 135 BUG_ON(!q->irq_ptr->sch_token);
136 qperf_inc(q, eqbs); 136 qperf_inc(q, eqbs);
@@ -141,30 +141,34 @@ again:
141 ccq = do_eqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count, 141 ccq = do_eqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count,
142 auto_ack); 142 auto_ack);
143 rc = qdio_check_ccq(q, ccq); 143 rc = qdio_check_ccq(q, ccq);
144 144 if (!rc)
145 /* At least one buffer was processed, return and extract the remaining 145 return count - tmp_count;
146 * buffers later.
147 */
148 if ((ccq == 96) && (count != tmp_count)) {
149 qperf_inc(q, eqbs_partial);
150 return (count - tmp_count);
151 }
152 146
153 if (rc == 1) { 147 if (rc == 1) {
154 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS again:%2d", ccq); 148 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS again:%2d", ccq);
155 goto again; 149 goto again;
156 } 150 }
157 151
158 if (rc < 0) { 152 if (rc == 2) {
159 DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); 153 BUG_ON(tmp_count == count);
160 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 154 qperf_inc(q, eqbs_partial);
161 q->handler(q->irq_ptr->cdev, 155 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x",
162 QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 156 tmp_count);
163 q->nr, q->first_to_kick, count, 157 /*
164 q->irq_ptr->int_parm); 158 * Retry once, if that fails bail out and process the
165 return 0; 159 * extracted buffers before trying again.
160 */
161 if (!retried++)
162 goto again;
163 else
164 return count - tmp_count;
166 } 165 }
167 return count - tmp_count; 166
167 DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
168 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
169 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
170 0, -1, -1, q->irq_ptr->int_parm);
171 return 0;
168} 172}
169 173
170/** 174/**
@@ -197,22 +201,22 @@ static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start,
197again: 201again:
198 ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count); 202 ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count);
199 rc = qdio_check_ccq(q, ccq); 203 rc = qdio_check_ccq(q, ccq);
200 if (rc == 1) { 204 if (!rc) {
205 WARN_ON(tmp_count);
206 return count - tmp_count;
207 }
208
209 if (rc == 1 || rc == 2) {
201 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq); 210 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq);
202 qperf_inc(q, sqbs_partial); 211 qperf_inc(q, sqbs_partial);
203 goto again; 212 goto again;
204 } 213 }
205 if (rc < 0) { 214
206 DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); 215 DBF_ERROR("%4x SQBS ERROR", SCH_NO(q));
207 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 216 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
208 q->handler(q->irq_ptr->cdev, 217 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
209 QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 218 0, -1, -1, q->irq_ptr->int_parm);
210 q->nr, q->first_to_kick, count, 219 return 0;
211 q->irq_ptr->int_parm);
212 return 0;
213 }
214 WARN_ON(tmp_count);
215 return count - tmp_count;
216} 220}
217 221
218/* returns number of examined buffers and their common state in *state */ 222/* returns number of examined buffers and their common state in *state */
@@ -277,7 +281,7 @@ static inline int set_buf_state(struct qdio_q *q, int bufnr,
277} 281}
278 282
279/* set slsb states to initial state */ 283/* set slsb states to initial state */
280void qdio_init_buf_states(struct qdio_irq *irq_ptr) 284static void qdio_init_buf_states(struct qdio_irq *irq_ptr)
281{ 285{
282 struct qdio_q *q; 286 struct qdio_q *q;
283 int i; 287 int i;
@@ -446,7 +450,7 @@ static void process_buffer_error(struct qdio_q *q, int count)
446 qperf_inc(q, target_full); 450 qperf_inc(q, target_full);
447 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", 451 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x",
448 q->first_to_check); 452 q->first_to_check);
449 return; 453 goto set;
450 } 454 }
451 455
452 DBF_ERROR("%4x BUF ERROR", SCH_NO(q)); 456 DBF_ERROR("%4x BUF ERROR", SCH_NO(q));
@@ -456,6 +460,7 @@ static void process_buffer_error(struct qdio_q *q, int count)
456 q->sbal[q->first_to_check]->element[14].sflags, 460 q->sbal[q->first_to_check]->element[14].sflags,
457 q->sbal[q->first_to_check]->element[15].sflags); 461 q->sbal[q->first_to_check]->element[15].sflags);
458 462
463set:
459 /* 464 /*
460 * Interrupts may be avoided as long as the error is present 465 * Interrupts may be avoided as long as the error is present
461 * so change the buffer state immediately to avoid starvation. 466 * so change the buffer state immediately to avoid starvation.
@@ -513,6 +518,8 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
513 int count, stop; 518 int count, stop;
514 unsigned char state = 0; 519 unsigned char state = 0;
515 520
521 q->timestamp = get_clock_fast();
522
516 /* 523 /*
517 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved 524 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved
518 * would return 0. 525 * would return 0.
@@ -782,6 +789,8 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
782 int count, stop; 789 int count, stop;
783 unsigned char state = 0; 790 unsigned char state = 0;
784 791
792 q->timestamp = get_clock_fast();
793
785 if (need_siga_sync(q)) 794 if (need_siga_sync(q))
786 if (((queue_type(q) != QDIO_IQDIO_QFMT) && 795 if (((queue_type(q) != QDIO_IQDIO_QFMT) &&
787 !pci_out_supported(q)) || 796 !pci_out_supported(q)) ||
@@ -912,21 +921,13 @@ static void __qdio_outbound_processing(struct qdio_q *q)
912 if (!pci_out_supported(q) && !qdio_outbound_q_done(q)) 921 if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
913 goto sched; 922 goto sched;
914 923
915 /* bail out for HiperSockets unicast queues */
916 if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
917 return;
918
919 if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
920 (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
921 goto sched;
922
923 if (q->u.out.pci_out_enabled) 924 if (q->u.out.pci_out_enabled)
924 return; 925 return;
925 926
926 /* 927 /*
927 * Now we know that queue type is either qeth without pci enabled 928 * Now we know that queue type is either qeth without pci enabled
928 * or HiperSockets multicast. Make sure buffer switch from PRIMED to 929 * or HiperSockets. Make sure buffer switch from PRIMED to EMPTY
929 * EMPTY is noticed and outbound_handler is called after some time. 930 * is noticed and outbound_handler is called after some time.
930 */ 931 */
931 if (qdio_outbound_q_done(q)) 932 if (qdio_outbound_q_done(q))
932 del_timer(&q->u.out.timer); 933 del_timer(&q->u.out.timer);
@@ -1128,7 +1129,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
1128 return; 1129 return;
1129 } 1130 }
1130 1131
1131 kstat_cpu(smp_processor_id()).irqs[IOINT_QDI]++;
1132 if (irq_ptr->perf_stat_enabled) 1132 if (irq_ptr->perf_stat_enabled)
1133 irq_ptr->perf_stat.qdio_int++; 1133 irq_ptr->perf_stat.qdio_int++;
1134 1134
@@ -1719,9 +1719,7 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
1719 1719
1720 WARN_ON(queue_irqs_enabled(q)); 1720 WARN_ON(queue_irqs_enabled(q));
1721 1721
1722 if (!shared_ind(q)) 1722 clear_nonshared_ind(irq_ptr);
1723 xchg(q->irq_ptr->dsci, 0);
1724
1725 qdio_stop_polling(q); 1723 qdio_stop_polling(q);
1726 clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state); 1724 clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);
1727 1725
@@ -1729,7 +1727,7 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
1729 * We need to check again to not lose initiative after 1727 * We need to check again to not lose initiative after
1730 * resetting the ACK state. 1728 * resetting the ACK state.
1731 */ 1729 */
1732 if (!shared_ind(q) && *q->irq_ptr->dsci) 1730 if (test_nonshared_ind(irq_ptr))
1733 goto rescan; 1731 goto rescan;
1734 if (!qdio_inbound_q_done(q)) 1732 if (!qdio_inbound_q_done(q))
1735 goto rescan; 1733 goto rescan;
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index a3e3949d7b69..011eadea3ee4 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -26,17 +26,24 @@
26 */ 26 */
27#define TIQDIO_NR_NONSHARED_IND 63 27#define TIQDIO_NR_NONSHARED_IND 63
28#define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1) 28#define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1)
29#define TIQDIO_SHARED_IND 63
30
31/* device state change indicators */
32struct indicator_t {
33 u32 ind; /* u32 because of compare-and-swap performance */
34 atomic_t count; /* use count, 0 or 1 for non-shared indicators */
35};
29 36
30/* list of thin interrupt input queues */ 37/* list of thin interrupt input queues */
31static LIST_HEAD(tiq_list); 38static LIST_HEAD(tiq_list);
32DEFINE_MUTEX(tiq_list_lock); 39static DEFINE_MUTEX(tiq_list_lock);
33 40
34/* adapter local summary indicator */ 41/* adapter local summary indicator */
35static u8 *tiqdio_alsi; 42static u8 *tiqdio_alsi;
36 43
37struct indicator_t *q_indicators; 44static struct indicator_t *q_indicators;
38 45
39static u64 last_ai_time; 46u64 last_ai_time;
40 47
41/* returns addr for the device state change indicator */ 48/* returns addr for the device state change indicator */
42static u32 *get_indicator(void) 49static u32 *get_indicator(void)
@@ -90,6 +97,43 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
90 synchronize_rcu(); 97 synchronize_rcu();
91} 98}
92 99
100static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr)
101{
102 return irq_ptr->nr_input_qs > 1;
103}
104
105static inline int references_shared_dsci(struct qdio_irq *irq_ptr)
106{
107 return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
108}
109
110static inline int shared_ind(struct qdio_irq *irq_ptr)
111{
112 return references_shared_dsci(irq_ptr) ||
113 has_multiple_inq_on_dsci(irq_ptr);
114}
115
116void clear_nonshared_ind(struct qdio_irq *irq_ptr)
117{
118 if (!is_thinint_irq(irq_ptr))
119 return;
120 if (shared_ind(irq_ptr))
121 return;
122 xchg(irq_ptr->dsci, 0);
123}
124
125int test_nonshared_ind(struct qdio_irq *irq_ptr)
126{
127 if (!is_thinint_irq(irq_ptr))
128 return 0;
129 if (shared_ind(irq_ptr))
130 return 0;
131 if (*irq_ptr->dsci)
132 return 1;
133 else
134 return 0;
135}
136
93static inline u32 clear_shared_ind(void) 137static inline u32 clear_shared_ind(void)
94{ 138{
95 if (!atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) 139 if (!atomic_read(&q_indicators[TIQDIO_SHARED_IND].count))
@@ -119,7 +163,7 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
119 q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, 163 q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
120 q->irq_ptr->int_parm); 164 q->irq_ptr->int_parm);
121 } else { 165 } else {
122 if (!shared_ind(q)) 166 if (!shared_ind(q->irq_ptr))
123 xchg(q->irq_ptr->dsci, 0); 167 xchg(q->irq_ptr->dsci, 0);
124 168
125 /* 169 /*
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index aec60d55b10d..3c2c923d5c0a 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -33,7 +33,7 @@
33 * The pointer to our (page) of device descriptions. 33 * The pointer to our (page) of device descriptions.
34 */ 34 */
35static void *kvm_devices; 35static void *kvm_devices;
36struct work_struct hotplug_work; 36static struct work_struct hotplug_work;
37 37
38struct kvm_device { 38struct kvm_device {
39 struct virtio_device vdev; 39 struct virtio_device vdev;
@@ -334,10 +334,10 @@ static void scan_devices(void)
334 */ 334 */
335static int match_desc(struct device *dev, void *data) 335static int match_desc(struct device *dev, void *data)
336{ 336{
337 if ((ulong)to_kvmdev(dev_to_virtio(dev))->desc == (ulong)data) 337 struct virtio_device *vdev = dev_to_virtio(dev);
338 return 1; 338 struct kvm_device *kdev = to_kvmdev(vdev);
339 339
340 return 0; 340 return kdev->desc == data;
341} 341}
342 342
343/* 343/*
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index f1fa2483ae6b..b41fae37d3af 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -63,7 +63,6 @@
63 63
64#define KMSG_COMPONENT "claw" 64#define KMSG_COMPONENT "claw"
65 65
66#include <linux/kernel_stat.h>
67#include <asm/ccwdev.h> 66#include <asm/ccwdev.h>
68#include <asm/ccwgroup.h> 67#include <asm/ccwgroup.h>
69#include <asm/debug.h> 68#include <asm/debug.h>
@@ -291,6 +290,7 @@ static struct ccw_driver claw_ccw_driver = {
291 .ids = claw_ids, 290 .ids = claw_ids,
292 .probe = ccwgroup_probe_ccwdev, 291 .probe = ccwgroup_probe_ccwdev,
293 .remove = ccwgroup_remove_ccwdev, 292 .remove = ccwgroup_remove_ccwdev,
293 .int_class = IOINT_CLW,
294}; 294};
295 295
296static ssize_t 296static ssize_t
@@ -645,7 +645,6 @@ claw_irq_handler(struct ccw_device *cdev,
645 struct claw_env *p_env; 645 struct claw_env *p_env;
646 struct chbk *p_ch_r=NULL; 646 struct chbk *p_ch_r=NULL;
647 647
648 kstat_cpu(smp_processor_id()).irqs[IOINT_CLW]++;
649 CLAW_DBF_TEXT(4, trace, "clawirq"); 648 CLAW_DBF_TEXT(4, trace, "clawirq");
650 /* Bypass all 'unsolicited interrupts' */ 649 /* Bypass all 'unsolicited interrupts' */
651 privptr = dev_get_drvdata(&cdev->dev); 650 privptr = dev_get_drvdata(&cdev->dev);
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 426787efc492..5cb93a8e3403 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -24,7 +24,6 @@
24#define KMSG_COMPONENT "ctcm" 24#define KMSG_COMPONENT "ctcm"
25#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 25#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
26 26
27#include <linux/kernel_stat.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
@@ -1203,7 +1202,6 @@ static void ctcm_irq_handler(struct ccw_device *cdev,
1203 int cstat; 1202 int cstat;
1204 int dstat; 1203 int dstat;
1205 1204
1206 kstat_cpu(smp_processor_id()).irqs[IOINT_CTC]++;
1207 CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG, 1205 CTCM_DBF_TEXT_(TRACE, CTC_DBF_DEBUG,
1208 "Enter %s(%s)", CTCM_FUNTAIL, dev_name(&cdev->dev)); 1206 "Enter %s(%s)", CTCM_FUNTAIL, dev_name(&cdev->dev));
1209 1207
@@ -1769,6 +1767,7 @@ static struct ccw_driver ctcm_ccw_driver = {
1769 .ids = ctcm_ids, 1767 .ids = ctcm_ids,
1770 .probe = ccwgroup_probe_ccwdev, 1768 .probe = ccwgroup_probe_ccwdev,
1771 .remove = ccwgroup_remove_ccwdev, 1769 .remove = ccwgroup_remove_ccwdev,
1770 .int_class = IOINT_CTC,
1772}; 1771};
1773 1772
1774static struct ccwgroup_driver ctcm_group_driver = { 1773static struct ccwgroup_driver ctcm_group_driver = {
diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c
index 8305319b2a84..650aec1839e9 100644
--- a/drivers/s390/net/ctcm_sysfs.c
+++ b/drivers/s390/net/ctcm_sysfs.c
@@ -159,7 +159,7 @@ static ssize_t ctcm_proto_store(struct device *dev,
159 return count; 159 return count;
160} 160}
161 161
162const char *ctcm_type[] = { 162static const char *ctcm_type[] = {
163 "not a channel", 163 "not a channel",
164 "CTC/A", 164 "CTC/A",
165 "FICON channel", 165 "FICON channel",
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index fb246b944b16..c28713da1ec5 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -26,7 +26,6 @@
26#define KMSG_COMPONENT "lcs" 26#define KMSG_COMPONENT "lcs"
27#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 27#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
28 28
29#include <linux/kernel_stat.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/if.h> 30#include <linux/if.h>
32#include <linux/netdevice.h> 31#include <linux/netdevice.h>
@@ -1399,7 +1398,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1399 int rc, index; 1398 int rc, index;
1400 int cstat, dstat; 1399 int cstat, dstat;
1401 1400
1402 kstat_cpu(smp_processor_id()).irqs[IOINT_LCS]++;
1403 if (lcs_check_irb_error(cdev, irb)) 1401 if (lcs_check_irb_error(cdev, irb))
1404 return; 1402 return;
1405 1403
@@ -1972,7 +1970,7 @@ lcs_portno_store (struct device *dev, struct device_attribute *attr, const char
1972 1970
1973static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store); 1971static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store);
1974 1972
1975const char *lcs_type[] = { 1973static const char *lcs_type[] = {
1976 "not a channel", 1974 "not a channel",
1977 "2216 parallel", 1975 "2216 parallel",
1978 "2216 channel", 1976 "2216 channel",
@@ -2399,6 +2397,7 @@ static struct ccw_driver lcs_ccw_driver = {
2399 .ids = lcs_ids, 2397 .ids = lcs_ids,
2400 .probe = ccwgroup_probe_ccwdev, 2398 .probe = ccwgroup_probe_ccwdev,
2401 .remove = ccwgroup_remove_ccwdev, 2399 .remove = ccwgroup_remove_ccwdev,
2400 .int_class = IOINT_LCS,
2402}; 2401};
2403 2402
2404/** 2403/**
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index ce735204d317..e4c1176ee25b 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1415,7 +1415,7 @@ static int qeth_l3_send_checksum_command(struct qeth_card *card)
1415 return 0; 1415 return 0;
1416} 1416}
1417 1417
1418int qeth_l3_set_rx_csum(struct qeth_card *card, int on) 1418static int qeth_l3_set_rx_csum(struct qeth_card *card, int on)
1419{ 1419{
1420 int rc = 0; 1420 int rc = 0;
1421 1421