diff options
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/css.c | 7 | ||||
-rw-r--r-- | drivers/s390/cio/css.h | 3 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 8 | ||||
-rw-r--r-- | drivers/s390/cio/idset.c | 25 | ||||
-rw-r--r-- | drivers/s390/cio/idset.h | 3 |
5 files changed, 22 insertions, 24 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index b4d572f65f07..fd00afd8b850 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -377,7 +377,11 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) | |||
377 | /* Will be done on the slow path. */ | 377 | /* Will be done on the slow path. */ |
378 | return -EAGAIN; | 378 | return -EAGAIN; |
379 | } | 379 | } |
380 | if (stsch_err(schid, &schib) || !css_sch_is_valid(&schib)) { | 380 | if (stsch_err(schid, &schib)) { |
381 | /* Subchannel is not provided. */ | ||
382 | return -ENXIO; | ||
383 | } | ||
384 | if (!css_sch_is_valid(&schib)) { | ||
381 | /* Unusable - ignore. */ | 385 | /* Unusable - ignore. */ |
382 | return 0; | 386 | return 0; |
383 | } | 387 | } |
@@ -536,6 +540,7 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data) | |||
536 | case -ENOMEM: | 540 | case -ENOMEM: |
537 | case -EIO: | 541 | case -EIO: |
538 | /* These should abort looping */ | 542 | /* These should abort looping */ |
543 | idset_sch_del_subseq(slow_subchannel_set, schid); | ||
539 | break; | 544 | break; |
540 | default: | 545 | default: |
541 | rc = 0; | 546 | rc = 0; |
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 33bb4d891e16..4af3dfe70ef5 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h | |||
@@ -112,9 +112,6 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); | |||
112 | extern void css_reiterate_subchannels(void); | 112 | extern void css_reiterate_subchannels(void); |
113 | void css_update_ssd_info(struct subchannel *sch); | 113 | void css_update_ssd_info(struct subchannel *sch); |
114 | 114 | ||
115 | #define __MAX_SUBCHANNEL 65535 | ||
116 | #define __MAX_SSID 3 | ||
117 | |||
118 | struct channel_subsystem { | 115 | struct channel_subsystem { |
119 | u8 cssid; | 116 | u8 cssid; |
120 | int valid; | 117 | int valid; |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index fc916f5d7314..fd3143c291c6 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -1424,7 +1424,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch) | |||
1424 | } | 1424 | } |
1425 | if (device_is_disconnected(cdev)) | 1425 | if (device_is_disconnected(cdev)) |
1426 | return IO_SCH_REPROBE; | 1426 | return IO_SCH_REPROBE; |
1427 | if (cdev->online) | 1427 | if (cdev->online && !cdev->private->flags.resuming) |
1428 | return IO_SCH_VERIFY; | 1428 | return IO_SCH_VERIFY; |
1429 | if (cdev->private->state == DEV_STATE_NOT_OPER) | 1429 | if (cdev->private->state == DEV_STATE_NOT_OPER) |
1430 | return IO_SCH_UNREG_ATTACH; | 1430 | return IO_SCH_UNREG_ATTACH; |
@@ -1469,12 +1469,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) | |||
1469 | rc = 0; | 1469 | rc = 0; |
1470 | goto out_unlock; | 1470 | goto out_unlock; |
1471 | case IO_SCH_VERIFY: | 1471 | case IO_SCH_VERIFY: |
1472 | if (cdev->private->flags.resuming == 1) { | ||
1473 | if (cio_enable_subchannel(sch, (u32)(addr_t)sch)) { | ||
1474 | ccw_device_set_notoper(cdev); | ||
1475 | break; | ||
1476 | } | ||
1477 | } | ||
1478 | /* Trigger path verification. */ | 1472 | /* Trigger path verification. */ |
1479 | io_subchannel_verify(sch); | 1473 | io_subchannel_verify(sch); |
1480 | rc = 0; | 1474 | rc = 0; |
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c index e6d5f8c49524..65d13e38803f 100644 --- a/drivers/s390/cio/idset.c +++ b/drivers/s390/cio/idset.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright IBM Corp. 2007 | 2 | * Copyright IBM Corp. 2007, 2012 |
3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/vmalloc.h> | 6 | #include <linux/vmalloc.h> |
7 | #include <linux/bitmap.h> | ||
7 | #include <linux/bitops.h> | 8 | #include <linux/bitops.h> |
8 | #include "idset.h" | 9 | #include "idset.h" |
9 | #include "css.h" | 10 | #include "css.h" |
@@ -89,6 +90,14 @@ void idset_sch_del(struct idset *set, struct subchannel_id schid) | |||
89 | idset_del(set, schid.ssid, schid.sch_no); | 90 | idset_del(set, schid.ssid, schid.sch_no); |
90 | } | 91 | } |
91 | 92 | ||
93 | /* Clear ids starting from @schid up to end of subchannel set. */ | ||
94 | void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid) | ||
95 | { | ||
96 | int pos = schid.ssid * set->num_id + schid.sch_no; | ||
97 | |||
98 | bitmap_clear(set->bitmap, pos, set->num_id - schid.sch_no); | ||
99 | } | ||
100 | |||
92 | int idset_sch_contains(struct idset *set, struct subchannel_id schid) | 101 | int idset_sch_contains(struct idset *set, struct subchannel_id schid) |
93 | { | 102 | { |
94 | return idset_contains(set, schid.ssid, schid.sch_no); | 103 | return idset_contains(set, schid.ssid, schid.sch_no); |
@@ -111,20 +120,12 @@ int idset_sch_get_first(struct idset *set, struct subchannel_id *schid) | |||
111 | 120 | ||
112 | int idset_is_empty(struct idset *set) | 121 | int idset_is_empty(struct idset *set) |
113 | { | 122 | { |
114 | int bitnum; | 123 | return bitmap_empty(set->bitmap, set->num_ssid * set->num_id); |
115 | |||
116 | bitnum = find_first_bit(set->bitmap, set->num_ssid * set->num_id); | ||
117 | if (bitnum >= set->num_ssid * set->num_id) | ||
118 | return 1; | ||
119 | return 0; | ||
120 | } | 124 | } |
121 | 125 | ||
122 | void idset_add_set(struct idset *to, struct idset *from) | 126 | void idset_add_set(struct idset *to, struct idset *from) |
123 | { | 127 | { |
124 | unsigned long i, len; | 128 | int len = min(to->num_ssid * to->num_id, from->num_ssid * from->num_id); |
125 | 129 | ||
126 | len = min(__BITOPS_WORDS(to->num_ssid * to->num_id), | 130 | bitmap_or(to->bitmap, to->bitmap, from->bitmap, len); |
127 | __BITOPS_WORDS(from->num_ssid * from->num_id)); | ||
128 | for (i = 0; i < len ; i++) | ||
129 | to->bitmap[i] |= from->bitmap[i]; | ||
130 | } | 131 | } |
diff --git a/drivers/s390/cio/idset.h b/drivers/s390/cio/idset.h index 3d943f03591e..06d3bc01bb09 100644 --- a/drivers/s390/cio/idset.h +++ b/drivers/s390/cio/idset.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright IBM Corp. 2007 | 2 | * Copyright IBM Corp. 2007, 2012 |
3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 3 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -17,6 +17,7 @@ void idset_fill(struct idset *set); | |||
17 | struct idset *idset_sch_new(void); | 17 | struct idset *idset_sch_new(void); |
18 | void idset_sch_add(struct idset *set, struct subchannel_id id); | 18 | void idset_sch_add(struct idset *set, struct subchannel_id id); |
19 | void idset_sch_del(struct idset *set, struct subchannel_id id); | 19 | void idset_sch_del(struct idset *set, struct subchannel_id id); |
20 | void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid); | ||
20 | int idset_sch_contains(struct idset *set, struct subchannel_id id); | 21 | int idset_sch_contains(struct idset *set, struct subchannel_id id); |
21 | int idset_sch_get_first(struct idset *set, struct subchannel_id *id); | 22 | int idset_sch_get_first(struct idset *set, struct subchannel_id *id); |
22 | int idset_is_empty(struct idset *set); | 23 | int idset_is_empty(struct idset *set); |