1b804e8a6SJing Liu /*
2b804e8a6SJing Liu * Common device infrastructure for devices in the virtual css
3b804e8a6SJing Liu *
4b804e8a6SJing Liu * Copyright 2016 IBM Corp.
5b804e8a6SJing Liu * Author(s): Jing Liu <liujbjl@linux.vnet.ibm.com>
6b804e8a6SJing Liu *
7b804e8a6SJing Liu * This work is licensed under the terms of the GNU GPL, version 2 or (at
8b804e8a6SJing Liu * your option) any later version. See the COPYING file in the top-level
9b804e8a6SJing Liu * directory.
10b804e8a6SJing Liu */
110b8fa32fSMarkus Armbruster
12b804e8a6SJing Liu #include "qemu/osdep.h"
13b804e8a6SJing Liu #include "ccw-device.h"
14a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
150b8fa32fSMarkus Armbruster #include "qemu/module.h"
16bb185de4SJared Rossi #include "ipl.h"
17bb185de4SJared Rossi #include "qapi/visitor.h"
18bb185de4SJared Rossi #include "qemu/ctype.h"
19bb185de4SJared Rossi #include "qapi/error.h"
20b804e8a6SJing Liu
ccw_device_refill_ids(CcwDevice * dev)21d8d98db5SDong Jia Shi static void ccw_device_refill_ids(CcwDevice *dev)
22d8d98db5SDong Jia Shi {
23d8d98db5SDong Jia Shi SubchDev *sch = dev->sch;
24d8d98db5SDong Jia Shi
25d8d98db5SDong Jia Shi assert(sch);
26d8d98db5SDong Jia Shi
27d8d98db5SDong Jia Shi dev->dev_id.cssid = sch->cssid;
28d8d98db5SDong Jia Shi dev->dev_id.ssid = sch->ssid;
29d8d98db5SDong Jia Shi dev->dev_id.devid = sch->devno;
30d8d98db5SDong Jia Shi dev->dev_id.valid = true;
31d8d98db5SDong Jia Shi
32d8d98db5SDong Jia Shi dev->subch_id.cssid = sch->cssid;
33d8d98db5SDong Jia Shi dev->subch_id.ssid = sch->ssid;
34d8d98db5SDong Jia Shi dev->subch_id.devid = sch->schid;
35d8d98db5SDong Jia Shi dev->subch_id.valid = true;
36d8d98db5SDong Jia Shi }
37d8d98db5SDong Jia Shi
ccw_device_realize(CcwDevice * dev,Error ** errp)384a6a90f3SCédric Le Goater static bool ccw_device_realize(CcwDevice *dev, Error **errp)
39d8d98db5SDong Jia Shi {
40d8d98db5SDong Jia Shi ccw_device_refill_ids(dev);
414a6a90f3SCédric Le Goater return true;
42d8d98db5SDong Jia Shi }
43d8d98db5SDong Jia Shi
ccw_device_get_loadparm(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)44bb185de4SJared Rossi static void ccw_device_get_loadparm(Object *obj, Visitor *v,
45bb185de4SJared Rossi const char *name, void *opaque,
46bb185de4SJared Rossi Error **errp)
47bb185de4SJared Rossi {
48bb185de4SJared Rossi CcwDevice *dev = CCW_DEVICE(obj);
49bb185de4SJared Rossi char *str = g_strndup((char *) dev->loadparm, sizeof(dev->loadparm));
50bb185de4SJared Rossi
51bb185de4SJared Rossi visit_type_str(v, name, &str, errp);
52bb185de4SJared Rossi g_free(str);
53bb185de4SJared Rossi }
54bb185de4SJared Rossi
ccw_device_set_loadparm(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)55bb185de4SJared Rossi static void ccw_device_set_loadparm(Object *obj, Visitor *v,
56bb185de4SJared Rossi const char *name, void *opaque,
57bb185de4SJared Rossi Error **errp)
58bb185de4SJared Rossi {
59bb185de4SJared Rossi CcwDevice *dev = CCW_DEVICE(obj);
60bb185de4SJared Rossi char *val;
61bb185de4SJared Rossi int index;
62bb185de4SJared Rossi
63bb185de4SJared Rossi index = object_property_get_int(obj, "bootindex", NULL);
64bb185de4SJared Rossi
65bb185de4SJared Rossi if (index < 0) {
66bb185de4SJared Rossi error_setg(errp, "LOADPARM is only valid for boot devices!");
67bb185de4SJared Rossi }
68bb185de4SJared Rossi
69bb185de4SJared Rossi if (!visit_type_str(v, name, &val, errp)) {
70bb185de4SJared Rossi return;
71bb185de4SJared Rossi }
72bb185de4SJared Rossi
73bb185de4SJared Rossi s390_ipl_fmt_loadparm(dev->loadparm, val, errp);
74bb185de4SJared Rossi }
75bb185de4SJared Rossi
76*6e7c96aeSThomas Huth const PropertyInfo ccw_loadparm = {
77bb185de4SJared Rossi .name = "ccw_loadparm",
78bb185de4SJared Rossi .description = "Up to 8 chars in set of [A-Za-z0-9. ] to pass"
79bb185de4SJared Rossi " to the guest loader/kernel",
80bb185de4SJared Rossi .get = ccw_device_get_loadparm,
81bb185de4SJared Rossi .set = ccw_device_set_loadparm,
82bb185de4SJared Rossi };
83bb185de4SJared Rossi
84d8d98db5SDong Jia Shi static Property ccw_device_properties[] = {
852a78ac66SDong Jia Shi DEFINE_PROP_CSS_DEV_ID("devno", CcwDevice, devno),
86d8d98db5SDong Jia Shi DEFINE_PROP_CSS_DEV_ID_RO("dev_id", CcwDevice, dev_id),
87d8d98db5SDong Jia Shi DEFINE_PROP_CSS_DEV_ID_RO("subch_id", CcwDevice, subch_id),
88d8d98db5SDong Jia Shi DEFINE_PROP_END_OF_LIST(),
89d8d98db5SDong Jia Shi };
90d8d98db5SDong Jia Shi
ccw_device_reset_hold(Object * obj,ResetType type)916a0e10b7SPeter Maydell static void ccw_device_reset_hold(Object *obj, ResetType type)
92838fb84fSCornelia Huck {
936a0e10b7SPeter Maydell CcwDevice *ccw_dev = CCW_DEVICE(obj);
94838fb84fSCornelia Huck
95838fb84fSCornelia Huck css_reset_sch(ccw_dev->sch);
96838fb84fSCornelia Huck }
97838fb84fSCornelia Huck
ccw_device_class_init(ObjectClass * klass,void * data)98d8d98db5SDong Jia Shi static void ccw_device_class_init(ObjectClass *klass, void *data)
99d8d98db5SDong Jia Shi {
100d8d98db5SDong Jia Shi DeviceClass *dc = DEVICE_CLASS(klass);
101d8d98db5SDong Jia Shi CCWDeviceClass *k = CCW_DEVICE_CLASS(klass);
1026a0e10b7SPeter Maydell ResettableClass *rc = RESETTABLE_CLASS(klass);
103d8d98db5SDong Jia Shi
104d8d98db5SDong Jia Shi k->realize = ccw_device_realize;
105d8d98db5SDong Jia Shi k->refill_ids = ccw_device_refill_ids;
1064f67d30bSMarc-André Lureau device_class_set_props(dc, ccw_device_properties);
1076a0e10b7SPeter Maydell rc->phases.hold = ccw_device_reset_hold;
108a6d8b731SPhilippe Mathieu-Daudé dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
109d8d98db5SDong Jia Shi }
110d8d98db5SDong Jia Shi
111517ff12cSHalil Pasic const VMStateDescription vmstate_ccw_dev = {
112517ff12cSHalil Pasic .name = "s390_ccw_dev",
113517ff12cSHalil Pasic .version_id = 1,
114517ff12cSHalil Pasic .minimum_version_id = 1,
115b9b59a36SRichard Henderson .fields = (const VMStateField[]) {
116517ff12cSHalil Pasic VMSTATE_STRUCT_POINTER(sch, CcwDevice, vmstate_subch_dev, SubchDev),
117517ff12cSHalil Pasic VMSTATE_END_OF_LIST()
118517ff12cSHalil Pasic }
119517ff12cSHalil Pasic };
120517ff12cSHalil Pasic
121b804e8a6SJing Liu static const TypeInfo ccw_device_info = {
122b804e8a6SJing Liu .name = TYPE_CCW_DEVICE,
123b804e8a6SJing Liu .parent = TYPE_DEVICE,
124b804e8a6SJing Liu .instance_size = sizeof(CcwDevice),
125b804e8a6SJing Liu .class_size = sizeof(CCWDeviceClass),
126d8d98db5SDong Jia Shi .class_init = ccw_device_class_init,
127b804e8a6SJing Liu .abstract = true,
128b804e8a6SJing Liu };
129b804e8a6SJing Liu
ccw_device_register(void)130b804e8a6SJing Liu static void ccw_device_register(void)
131b804e8a6SJing Liu {
132b804e8a6SJing Liu type_register_static(&ccw_device_info);
133b804e8a6SJing Liu }
134b804e8a6SJing Liu
135b804e8a6SJing Liu type_init(ccw_device_register)
136