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>
This commit is contained in:
parent
afdfed0f86
commit
14556b33f2
|
@ -749,9 +749,16 @@ int cio_is_console(struct subchannel_id schid)
|
||||||
return schid_equal(&schid, &console_sch->schid);
|
return schid_equal(&schid, &console_sch->schid);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct subchannel *cio_get_console_subchannel(void)
|
void cio_register_early_subchannels(void)
|
||||||
{
|
{
|
||||||
return console_sch;
|
int ret;
|
||||||
|
|
||||||
|
if (!console_sch)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ret = css_register_subchannel(console_sch);
|
||||||
|
if (ret)
|
||||||
|
put_device(&console_sch->dev);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_CCW_CONSOLE */
|
#endif /* CONFIG_CCW_CONSOLE */
|
||||||
|
|
||||||
|
|
|
@ -129,11 +129,11 @@ void do_IRQ(struct pt_regs *);
|
||||||
#ifdef CONFIG_CCW_CONSOLE
|
#ifdef CONFIG_CCW_CONSOLE
|
||||||
extern struct subchannel *cio_probe_console(void);
|
extern struct subchannel *cio_probe_console(void);
|
||||||
extern int cio_is_console(struct subchannel_id);
|
extern int cio_is_console(struct subchannel_id);
|
||||||
extern struct subchannel *cio_get_console_subchannel(void);
|
extern void cio_register_early_subchannels(void);
|
||||||
extern void cio_tsch(struct subchannel *sch);
|
extern void cio_tsch(struct subchannel *sch);
|
||||||
#else
|
#else
|
||||||
#define cio_is_console(schid) 0
|
#define cio_is_console(schid) 0
|
||||||
#define cio_get_console_subchannel() NULL
|
static inline void cio_register_early_subchannels(void) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -224,17 +224,12 @@ void css_update_ssd_info(struct subchannel *sch)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (cio_is_console(sch->schid)) {
|
|
||||||
/* Console is initialized too early for functions requiring
|
|
||||||
* memory allocation. */
|
|
||||||
ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw);
|
|
||||||
} else {
|
|
||||||
ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info);
|
ret = chsc_get_ssd_info(sch->schid, &sch->ssd_info);
|
||||||
if (ret)
|
if (ret)
|
||||||
ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw);
|
ssd_from_pmcw(&sch->ssd_info, &sch->schib.pmcw);
|
||||||
|
|
||||||
ssd_register_chpids(&sch->ssd_info);
|
ssd_register_chpids(&sch->ssd_info);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t type_show(struct device *dev, struct device_attribute *attr,
|
static ssize_t type_show(struct device *dev, struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
|
@ -271,7 +266,7 @@ static const struct attribute_group *default_subch_attr_groups[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int css_register_subchannel(struct subchannel *sch)
|
int css_register_subchannel(struct subchannel *sch)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -314,13 +309,10 @@ int css_probe_device(struct subchannel_id schid)
|
||||||
int ret;
|
int ret;
|
||||||
struct subchannel *sch;
|
struct subchannel *sch;
|
||||||
|
|
||||||
if (cio_is_console(schid))
|
|
||||||
sch = cio_get_console_subchannel();
|
|
||||||
else {
|
|
||||||
sch = css_alloc_subchannel(schid);
|
sch = css_alloc_subchannel(schid);
|
||||||
if (IS_ERR(sch))
|
if (IS_ERR(sch))
|
||||||
return PTR_ERR(sch);
|
return PTR_ERR(sch);
|
||||||
}
|
|
||||||
ret = css_register_subchannel(sch);
|
ret = css_register_subchannel(sch);
|
||||||
if (ret)
|
if (ret)
|
||||||
put_device(&sch->dev);
|
put_device(&sch->dev);
|
||||||
|
@ -864,8 +856,7 @@ static struct notifier_block css_power_notifier = {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that the driver core is running, we can setup our channel subsystem.
|
* Now that the driver core is running, we can setup our channel subsystem.
|
||||||
* The struct subchannel's are created during probing (except for the
|
* The struct subchannel's are created during probing.
|
||||||
* static console subchannel).
|
|
||||||
*/
|
*/
|
||||||
static int __init css_bus_init(void)
|
static int __init css_bus_init(void)
|
||||||
{
|
{
|
||||||
|
@ -1044,6 +1035,8 @@ int css_complete_work(void)
|
||||||
*/
|
*/
|
||||||
static int __init channel_subsystem_init_sync(void)
|
static int __init channel_subsystem_init_sync(void)
|
||||||
{
|
{
|
||||||
|
/* Register subchannels which are already in use. */
|
||||||
|
cio_register_early_subchannels();
|
||||||
/* Start initial subchannel evaluation. */
|
/* Start initial subchannel evaluation. */
|
||||||
css_schedule_eval_all();
|
css_schedule_eval_all();
|
||||||
css_complete_work();
|
css_complete_work();
|
||||||
|
|
|
@ -102,6 +102,7 @@ extern void css_driver_unregister(struct css_driver *);
|
||||||
|
|
||||||
extern void css_sch_device_unregister(struct subchannel *);
|
extern void css_sch_device_unregister(struct subchannel *);
|
||||||
extern int css_probe_device(struct subchannel_id);
|
extern int css_probe_device(struct subchannel_id);
|
||||||
|
extern int css_register_subchannel(struct subchannel *);
|
||||||
extern struct subchannel *css_alloc_subchannel(struct subchannel_id);
|
extern struct subchannel *css_alloc_subchannel(struct subchannel_id);
|
||||||
extern struct subchannel *get_subchannel_by_schid(struct subchannel_id);
|
extern struct subchannel *get_subchannel_by_schid(struct subchannel_id);
|
||||||
extern int css_init_done;
|
extern int css_init_done;
|
||||||
|
|
Loading…
Reference in New Issue