aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2009-03-26 10:24:11 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-26 10:24:14 -0400
commit90ac24a5aeb8d4bef001bd3589564a52846d0eee (patch)
treef57ed4032783a546507d244d147ce56f69b4c751 /drivers/s390/cio
parent87fa5af80cdd5053b27a546725948c2b74ec82b2 (diff)
[S390] cio: device scan oom fallback.
Since some callers rely on for_each_subchannel_staged to not fail, fall back to brute force scanning using get_subchannel_by_schid in case of a oom situation. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/css.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index a5fc56371ba8..1f2e424596af 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -83,6 +83,25 @@ static int call_fn_unknown_sch(struct subchannel_id schid, void *data)
83 return rc; 83 return rc;
84} 84}
85 85
86static int call_fn_all_sch(struct subchannel_id schid, void *data)
87{
88 struct cb_data *cb = data;
89 struct subchannel *sch;
90 int rc = 0;
91
92 sch = get_subchannel_by_schid(schid);
93 if (sch) {
94 if (cb->fn_known_sch)
95 rc = cb->fn_known_sch(sch, cb->data);
96 put_device(&sch->dev);
97 } else {
98 if (cb->fn_unknown_sch)
99 rc = cb->fn_unknown_sch(schid, cb->data);
100 }
101
102 return rc;
103}
104
86int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), 105int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
87 int (*fn_unknown)(struct subchannel_id, 106 int (*fn_unknown)(struct subchannel_id,
88 void *), void *data) 107 void *), void *data)
@@ -90,13 +109,17 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
90 struct cb_data cb; 109 struct cb_data cb;
91 int rc; 110 int rc;
92 111
93 cb.set = idset_sch_new();
94 if (!cb.set)
95 return -ENOMEM;
96 idset_fill(cb.set);
97 cb.data = data; 112 cb.data = data;
98 cb.fn_known_sch = fn_known; 113 cb.fn_known_sch = fn_known;
99 cb.fn_unknown_sch = fn_unknown; 114 cb.fn_unknown_sch = fn_unknown;
115
116 cb.set = idset_sch_new();
117 if (!cb.set)
118 /* fall back to brute force scanning in case of oom */
119 return for_each_subchannel(call_fn_all_sch, &cb);
120
121 idset_fill(cb.set);
122
100 /* Process registered subchannels. */ 123 /* Process registered subchannels. */
101 rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch); 124 rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch);
102 if (rc) 125 if (rc)