diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2008-07-14 03:58:44 -0400 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-07-14 04:02:05 -0400 |
commit | 7e9db9eaefdb8798730790214ff1b7746006ec98 (patch) | |
tree | a56f3ad00a018b735d3c2c645fbb2e138a72c578 /drivers/s390/cio/css.c | |
parent | 0ae7a7b250bdf7ee87c8346164ef3c47fb79dfbd (diff) |
[S390] cio: Introduce modalias for css bus.
Add modalias and subchannel type attributes for all subchannels.
I/O subchannel specific attributes are now created in
io_subchannel_probe(). modalias and subchannel type are also
added to the uevent for the css bus. Also make the css modalias
known.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/css.c')
-rw-r--r-- | drivers/s390/cio/css.c | 69 |
1 files changed, 63 insertions, 6 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index b7f4b52c5a9a..53e7496dc90c 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -2,8 +2,7 @@ | |||
2 | * drivers/s390/cio/css.c | 2 | * drivers/s390/cio/css.c |
3 | * driver for channel subsystem | 3 | * driver for channel subsystem |
4 | * | 4 | * |
5 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, | 5 | * Copyright IBM Corp. 2002,2008 |
6 | * IBM Corporation | ||
7 | * Author(s): Arnd Bergmann (arndb@de.ibm.com) | 6 | * Author(s): Arnd Bergmann (arndb@de.ibm.com) |
8 | * Cornelia Huck (cornelia.huck@de.ibm.com) | 7 | * Cornelia Huck (cornelia.huck@de.ibm.com) |
9 | */ | 8 | */ |
@@ -210,6 +209,41 @@ void css_update_ssd_info(struct subchannel *sch) | |||
210 | } | 209 | } |
211 | } | 210 | } |
212 | 211 | ||
212 | static ssize_t type_show(struct device *dev, struct device_attribute *attr, | ||
213 | char *buf) | ||
214 | { | ||
215 | struct subchannel *sch = to_subchannel(dev); | ||
216 | |||
217 | return sprintf(buf, "%01x\n", sch->st); | ||
218 | } | ||
219 | |||
220 | static DEVICE_ATTR(type, 0444, type_show, NULL); | ||
221 | |||
222 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | ||
223 | char *buf) | ||
224 | { | ||
225 | struct subchannel *sch = to_subchannel(dev); | ||
226 | |||
227 | return sprintf(buf, "css:t%01X\n", sch->st); | ||
228 | } | ||
229 | |||
230 | static DEVICE_ATTR(modalias, 0444, modalias_show, NULL); | ||
231 | |||
232 | static struct attribute *subch_attrs[] = { | ||
233 | &dev_attr_type.attr, | ||
234 | &dev_attr_modalias.attr, | ||
235 | NULL, | ||
236 | }; | ||
237 | |||
238 | static struct attribute_group subch_attr_group = { | ||
239 | .attrs = subch_attrs, | ||
240 | }; | ||
241 | |||
242 | static struct attribute_group *default_subch_attr_groups[] = { | ||
243 | &subch_attr_group, | ||
244 | NULL, | ||
245 | }; | ||
246 | |||
213 | static int css_register_subchannel(struct subchannel *sch) | 247 | static int css_register_subchannel(struct subchannel *sch) |
214 | { | 248 | { |
215 | int ret; | 249 | int ret; |
@@ -218,16 +252,17 @@ static int css_register_subchannel(struct subchannel *sch) | |||
218 | sch->dev.parent = &channel_subsystems[0]->device; | 252 | sch->dev.parent = &channel_subsystems[0]->device; |
219 | sch->dev.bus = &css_bus_type; | 253 | sch->dev.bus = &css_bus_type; |
220 | sch->dev.release = &css_subchannel_release; | 254 | sch->dev.release = &css_subchannel_release; |
221 | sch->dev.groups = subch_attr_groups; | 255 | sch->dev.groups = default_subch_attr_groups; |
222 | /* | 256 | /* |
223 | * We don't want to generate uevents for I/O subchannels that don't | 257 | * We don't want to generate uevents for I/O subchannels that don't |
224 | * have a working ccw device behind them since they will be | 258 | * have a working ccw device behind them since they will be |
225 | * unregistered before they can be used anyway, so we delay the add | 259 | * unregistered before they can be used anyway, so we delay the add |
226 | * uevent until after device recognition was successful. | 260 | * uevent until after device recognition was successful. |
261 | * Note that we suppress the uevent for all subchannel types; | ||
262 | * the subchannel driver can decide itself when it wants to inform | ||
263 | * userspace of its existence. | ||
227 | */ | 264 | */ |
228 | if (!cio_is_console(sch->schid)) | 265 | sch->dev.uevent_suppress = 1; |
229 | /* Console is special, no need to suppress. */ | ||
230 | sch->dev.uevent_suppress = 1; | ||
231 | css_update_ssd_info(sch); | 266 | css_update_ssd_info(sch); |
232 | /* make it known to the system */ | 267 | /* make it known to the system */ |
233 | ret = css_sch_device_register(sch); | 268 | ret = css_sch_device_register(sch); |
@@ -236,6 +271,15 @@ static int css_register_subchannel(struct subchannel *sch) | |||
236 | sch->schid.ssid, sch->schid.sch_no, ret); | 271 | sch->schid.ssid, sch->schid.sch_no, ret); |
237 | return ret; | 272 | return ret; |
238 | } | 273 | } |
274 | if (!sch->driver) { | ||
275 | /* | ||
276 | * No driver matched. Generate the uevent now so that | ||
277 | * a fitting driver module may be loaded based on the | ||
278 | * modalias. | ||
279 | */ | ||
280 | sch->dev.uevent_suppress = 0; | ||
281 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | ||
282 | } | ||
239 | return ret; | 283 | return ret; |
240 | } | 284 | } |
241 | 285 | ||
@@ -926,12 +970,25 @@ static void css_shutdown(struct device *dev) | |||
926 | sch->driver->shutdown(sch); | 970 | sch->driver->shutdown(sch); |
927 | } | 971 | } |
928 | 972 | ||
973 | static int css_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
974 | { | ||
975 | struct subchannel *sch = to_subchannel(dev); | ||
976 | int ret; | ||
977 | |||
978 | ret = add_uevent_var(env, "ST=%01X", sch->st); | ||
979 | if (ret) | ||
980 | return ret; | ||
981 | ret = add_uevent_var(env, "MODALIAS=css:t%01X", sch->st); | ||
982 | return ret; | ||
983 | } | ||
984 | |||
929 | struct bus_type css_bus_type = { | 985 | struct bus_type css_bus_type = { |
930 | .name = "css", | 986 | .name = "css", |
931 | .match = css_bus_match, | 987 | .match = css_bus_match, |
932 | .probe = css_probe, | 988 | .probe = css_probe, |
933 | .remove = css_remove, | 989 | .remove = css_remove, |
934 | .shutdown = css_shutdown, | 990 | .shutdown = css_shutdown, |
991 | .uevent = css_uevent, | ||
935 | }; | 992 | }; |
936 | 993 | ||
937 | /** | 994 | /** |