aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2013-04-13 07:03:54 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-04-17 08:07:32 -0400
commit14556b33f2a5d6a3bc75cd33b709452a31555b25 (patch)
treeae937b86290af27d01e2ea5fd0b660f86a1a40a4
parentafdfed0f86d192c9957996d58d51c06ff2b9cb44 (diff)
s390/css: introduce cio_register_early_subchannels
Use cio_register_early_subchannels to register early subchannels which are already in use. Call this function before we do the actual subchannel scanning loop. This helps us to get rid of some more special cases regarding the console subchannel. Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/cio/cio.c11
-rw-r--r--drivers/s390/cio/cio.h4
-rw-r--r--drivers/s390/cio/css.c31
-rw-r--r--drivers/s390/cio/css.h1
4 files changed, 24 insertions, 23 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index ab99500604b7..3ab99d883888 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -749,9 +749,16 @@ int cio_is_console(struct subchannel_id schid)
749 return schid_equal(&schid, &console_sch->schid); 749 return schid_equal(&schid, &console_sch->schid);
750} 750}
751 751
752struct subchannel *cio_get_console_subchannel(void) 752void cio_register_early_subchannels(void)
753{ 753{
754 return console_sch; 754 int ret;
755
756 if (!console_sch)
757 return;
758
759 ret = css_register_subchannel(console_sch);
760 if (ret)
761 put_device(&console_sch->dev);
755} 762}
756#endif /* CONFIG_CCW_CONSOLE */ 763#endif /* CONFIG_CCW_CONSOLE */
757 764
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index 78975471ef28..57b41ec2ed40 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -129,11 +129,11 @@ void do_IRQ(struct pt_regs *);
129#ifdef CONFIG_CCW_CONSOLE 129#ifdef CONFIG_CCW_CONSOLE
130extern struct subchannel *cio_probe_console(void); 130extern struct subchannel *cio_probe_console(void);
131extern int cio_is_console(struct subchannel_id); 131extern int cio_is_console(struct subchannel_id);
132extern struct subchannel *cio_get_console_subchannel(void); 132extern void cio_register_early_subchannels(void);
133extern void cio_tsch(struct subchannel *sch); 133extern void cio_tsch(struct subchannel *sch);
134#else 134#else
135#define cio_is_console(schid) 0 135#define cio_is_console(schid) 0
136#define cio_get_console_subchannel() NULL 136static inline void cio_register_early_subchannels(void) {}
137#endif 137#endif
138 138
139#endif 139#endif
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index fb0e64f1845a..3b2245f58bde 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -224,16 +224,11 @@ void css_update_ssd_info(struct subchannel *sch)
224{ 224{
225 int ret; 225 int ret;
226 226
227 if (cio_is_console(sch->schid)) { 227 ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info);
228 /* Console is initialized too early for functions requiring 228 if (ret)
229 * memory allocation. */
230 ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw); 229 ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw);
231 } else { 230
232 ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info); 231 ssd_register_chpids(&sch->ssd_info);
233 if (ret)
234 ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw);
235 ssd_register_chpids(&sch->ssd_info);
236 }
237} 232}
238 233
239static ssize_t type_show(struct device *dev, struct device_attribute *attr, 234static ssize_t type_show(struct device *dev, struct device_attribute *attr,
@@ -271,7 +266,7 @@ static const struct attribute_group *default_subch_attr_groups[] = {
271 NULL, 266 NULL,
272}; 267};
273 268
274static int css_register_subchannel(struct subchannel *sch) 269int css_register_subchannel(struct subchannel *sch)
275{ 270{
276 int ret; 271 int ret;
277 272
@@ -314,13 +309,10 @@ int css_probe_device(struct subchannel_id schid)
314 int ret; 309 int ret;
315 struct subchannel *sch; 310 struct subchannel *sch;
316 311
317 if (cio_is_console(schid)) 312 sch = css_alloc_subchannel(schid);
318 sch = cio_get_console_subchannel(); 313 if (IS_ERR(sch))
319 else { 314 return PTR_ERR(sch);
320 sch = css_alloc_subchannel(schid); 315
321 if (IS_ERR(sch))
322 return PTR_ERR(sch);
323 }
324 ret = css_register_subchannel(sch); 316 ret = css_register_subchannel(sch);
325 if (ret) 317 if (ret)
326 put_device(&sch->dev); 318 put_device(&sch->dev);
@@ -864,8 +856,7 @@ static struct notifier_block css_power_notifier = {
864 856
865/* 857/*
866 * Now that the driver core is running, we can setup our channel subsystem. 858 * Now that the driver core is running, we can setup our channel subsystem.
867 * The struct subchannel's are created during probing (except for the 859 * The struct subchannel's are created during probing.
868 * static console subchannel).
869 */ 860 */
870static int __init css_bus_init(void) 861static int __init css_bus_init(void)
871{ 862{
@@ -1044,6 +1035,8 @@ int css_complete_work(void)
1044 */ 1035 */
1045static int __init channel_subsystem_init_sync(void) 1036static int __init channel_subsystem_init_sync(void)
1046{ 1037{
1038 /* Register subchannels which are already in use. */
1039 cio_register_early_subchannels();
1047 /* Start initial subchannel evaluation. */ 1040 /* Start initial subchannel evaluation. */
1048 css_schedule_eval_all(); 1041 css_schedule_eval_all();
1049 css_complete_work(); 1042 css_complete_work();
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 6ab424d753a9..2581b6986569 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -102,6 +102,7 @@ extern void css_driver_unregister(struct css_driver *);
102 102
103extern void css_sch_device_unregister(struct subchannel *); 103extern void css_sch_device_unregister(struct subchannel *);
104extern int css_probe_device(struct subchannel_id); 104extern int css_probe_device(struct subchannel_id);
105extern int css_register_subchannel(struct subchannel *);
105extern struct subchannel *css_alloc_subchannel(struct subchannel_id); 106extern struct subchannel *css_alloc_subchannel(struct subchannel_id);
106extern struct subchannel *get_subchannel_by_schid(struct subchannel_id); 107extern struct subchannel *get_subchannel_by_schid(struct subchannel_id);
107extern int css_init_done; 108extern int css_init_done;