]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/s390/cio/css.c
[S390] cio: fix rc generation after chsc call
[linux-2.6-omap-h63xx.git] / drivers / s390 / cio / css.c
index 8019288bc6dee0a730f79b6a4ed86228a3a052f3..1f2e424596af282b4937fd93fa30407930d5f2b4 100644 (file)
@@ -18,8 +18,8 @@
 #include <linux/list.h>
 #include <linux/reboot.h>
 #include <asm/isc.h>
+#include <asm/crw.h>
 
-#include "../s390mach.h"
 #include "css.h"
 #include "cio.h"
 #include "cio_debug.h"
@@ -83,6 +83,25 @@ static int call_fn_unknown_sch(struct subchannel_id schid, void *data)
        return rc;
 }
 
+static int call_fn_all_sch(struct subchannel_id schid, void *data)
+{
+       struct cb_data *cb = data;
+       struct subchannel *sch;
+       int rc = 0;
+
+       sch = get_subchannel_by_schid(schid);
+       if (sch) {
+               if (cb->fn_known_sch)
+                       rc = cb->fn_known_sch(sch, cb->data);
+               put_device(&sch->dev);
+       } else {
+               if (cb->fn_unknown_sch)
+                       rc = cb->fn_unknown_sch(schid, cb->data);
+       }
+
+       return rc;
+}
+
 int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
                               int (*fn_unknown)(struct subchannel_id,
                               void *), void *data)
@@ -90,13 +109,17 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
        struct cb_data cb;
        int rc;
 
-       cb.set = idset_sch_new();
-       if (!cb.set)
-               return -ENOMEM;
-       idset_fill(cb.set);
        cb.data = data;
        cb.fn_known_sch = fn_known;
        cb.fn_unknown_sch = fn_unknown;
+
+       cb.set = idset_sch_new();
+       if (!cb.set)
+               /* fall back to brute force scanning in case of oom */
+               return for_each_subchannel(call_fn_all_sch, &cb);
+
+       idset_fill(cb.set);
+
        /* Process registered subchannels. */
        rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch);
        if (rc)
@@ -765,7 +788,7 @@ init_channel_subsystem (void)
        if (ret)
                goto out;
 
-       ret = s390_register_crw_handler(CRW_RSC_SCH, css_process_crw);
+       ret = crw_register_handler(CRW_RSC_SCH, css_process_crw);
        if (ret)
                goto out;
 
@@ -845,7 +868,7 @@ out_unregister:
 out_bus:
        bus_unregister(&css_bus_type);
 out:
-       s390_unregister_crw_handler(CRW_RSC_CSS);
+       crw_unregister_handler(CRW_RSC_CSS);
        chsc_free_sei_area();
        kfree(slow_subchannel_set);
        pr_alert("The CSS device driver initialization failed with "