#include <linux/errno.h>
#include <linux/list.h>
#include <linux/reboot.h>
+#include <asm/isc.h>
#include "../s390mach.h"
#include "css.h"
struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1];
-int css_characteristics_avail = 0;
-
int
for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
{
return ret;
}
+/**
+ * css_sch_device_unregister - unregister a subchannel
+ * @sch: subchannel to be unregistered
+ */
void css_sch_device_unregister(struct subchannel *sch)
{
mutex_lock(&sch->reg_mutex);
- device_unregister(&sch->dev);
+ if (device_is_registered(&sch->dev))
+ device_unregister(&sch->dev);
mutex_unlock(&sch->reg_mutex);
}
+EXPORT_SYMBOL_GPL(css_sch_device_unregister);
static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw)
{
{
if ((schib->pmcw.st == SUBCHANNEL_TYPE_IO) && !schib->pmcw.dnv)
return 0;
+ if ((schib->pmcw.st == SUBCHANNEL_TYPE_MSG) && !schib->pmcw.w)
+ return 0;
return 1;
}
EXPORT_SYMBOL_GPL(css_sch_is_valid);
static void __init
css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
{
- if (css_characteristics_avail && css_general_characteristics.mcss) {
+ if (css_general_characteristics.mcss) {
css->global_pgid.pgid_high.ext_cssid.version = 0x80;
css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
} else {
ret = chsc_determine_css_characteristics();
if (ret == -ENOMEM)
goto out; /* No need to continue. */
- if (ret == 0)
- css_characteristics_avail = 1;
ret = chsc_alloc_sei_area();
if (ret)
ret = device_register(&css->device);
if (ret)
goto out_free_all;
- if (css_characteristics_avail &&
- css_chsc_characteristics.secm) {
+ if (css_chsc_characteristics.secm) {
ret = device_create_file(&css->device,
&dev_attr_cm_enable);
if (ret)
goto out_pseudo;
css_init_done = 1;
- ctl_set_bit(6, 28);
+ /* Enable default isc for I/O subchannels. */
+ isc_register(IO_SCH_ISC);
for_each_subchannel(__init_channel_subsystem, NULL);
return 0;
i--;
css = channel_subsystems[i];
device_unregister(&css->pseudo_subchannel->dev);
- if (css_characteristics_avail && css_chsc_characteristics.secm)
+ if (css_chsc_characteristics.secm)
device_remove_file(&css->device,
&dev_attr_cm_enable);
device_unregister(&css->device);
return sch == to_css(sch->dev.parent)->pseudo_subchannel;
}
-/*
- * find a driver for a subchannel. They identify by the subchannel
- * type with the exception that the console subchannel driver has its own
- * subchannel type although the device is an i/o subchannel
- */
-static int
-css_bus_match (struct device *dev, struct device_driver *drv)
+static int css_bus_match(struct device *dev, struct device_driver *drv)
{
struct subchannel *sch = to_subchannel(dev);
struct css_driver *driver = to_cssdriver(drv);
+ struct css_device_id *id;
- if (sch->st == driver->subchannel_type)
- return 1;
+ for (id = driver->subchannel_type; id->match_flags; id++) {
+ if (sch->st == id->type)
+ return 1;
+ }
return 0;
}
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(css_bus_type);
-EXPORT_SYMBOL_GPL(css_characteristics_avail);