aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device.c
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2008-07-14 03:58:44 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2008-07-14 04:02:05 -0400
commit7e9db9eaefdb8798730790214ff1b7746006ec98 (patch)
treea56f3ad00a018b735d3c2c645fbb2e138a72c578 /drivers/s390/cio/device.c
parent0ae7a7b250bdf7ee87c8346164ef3c47fb79dfbd (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/device.c')
-rw-r--r--drivers/s390/cio/device.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 0ed5a81260bc..23b129fd4d8d 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -585,19 +585,14 @@ static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);
585static DEVICE_ATTR(online, 0644, online_show, online_store); 585static DEVICE_ATTR(online, 0644, online_show, online_store);
586static DEVICE_ATTR(availability, 0444, available_show, NULL); 586static DEVICE_ATTR(availability, 0444, available_show, NULL);
587 587
588static struct attribute * subch_attrs[] = { 588static struct attribute *io_subchannel_attrs[] = {
589 &dev_attr_chpids.attr, 589 &dev_attr_chpids.attr,
590 &dev_attr_pimpampom.attr, 590 &dev_attr_pimpampom.attr,
591 NULL, 591 NULL,
592}; 592};
593 593
594static struct attribute_group subch_attr_group = { 594static struct attribute_group io_subchannel_attr_group = {
595 .attrs = subch_attrs, 595 .attrs = io_subchannel_attrs,
596};
597
598struct attribute_group *subch_attr_groups[] = {
599 &subch_attr_group,
600 NULL,
601}; 596};
602 597
603static struct attribute * ccwdev_attrs[] = { 598static struct attribute * ccwdev_attrs[] = {
@@ -1157,11 +1152,21 @@ static int io_subchannel_probe(struct subchannel *sch)
1157 1152
1158 cdev = sch_get_cdev(sch); 1153 cdev = sch_get_cdev(sch);
1159 if (cdev) { 1154 if (cdev) {
1155 rc = sysfs_create_group(&sch->dev.kobj,
1156 &io_subchannel_attr_group);
1157 if (rc)
1158 CIO_MSG_EVENT(0, "Failed to create io subchannel "
1159 "attributes for subchannel "
1160 "0.%x.%04x (rc=%d)\n",
1161 sch->schid.ssid, sch->schid.sch_no, rc);
1160 /* 1162 /*
1161 * This subchannel already has an associated ccw_device. 1163 * This subchannel already has an associated ccw_device.
1162 * Register it and exit. This happens for all early 1164 * Throw the delayed uevent for the subchannel, register
1163 * device, e.g. the console. 1165 * the ccw_device and exit. This happens for all early
1166 * devices, e.g. the console.
1164 */ 1167 */
1168 sch->dev.uevent_suppress = 0;
1169 kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
1165 cdev->dev.groups = ccwdev_attr_groups; 1170 cdev->dev.groups = ccwdev_attr_groups;
1166 device_initialize(&cdev->dev); 1171 device_initialize(&cdev->dev);
1167 ccw_device_register(cdev); 1172 ccw_device_register(cdev);
@@ -1184,11 +1189,17 @@ static int io_subchannel_probe(struct subchannel *sch)
1184 */ 1189 */
1185 dev_id.devno = sch->schib.pmcw.dev; 1190 dev_id.devno = sch->schib.pmcw.dev;
1186 dev_id.ssid = sch->schid.ssid; 1191 dev_id.ssid = sch->schid.ssid;
1192 rc = sysfs_create_group(&sch->dev.kobj,
1193 &io_subchannel_attr_group);
1194 if (rc)
1195 return rc;
1187 /* Allocate I/O subchannel private data. */ 1196 /* Allocate I/O subchannel private data. */
1188 sch->private = kzalloc(sizeof(struct io_subchannel_private), 1197 sch->private = kzalloc(sizeof(struct io_subchannel_private),
1189 GFP_KERNEL | GFP_DMA); 1198 GFP_KERNEL | GFP_DMA);
1190 if (!sch->private) 1199 if (!sch->private) {
1191 return -ENOMEM; 1200 rc = -ENOMEM;
1201 goto out_err;
1202 }
1192 cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL); 1203 cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL);
1193 if (!cdev) 1204 if (!cdev)
1194 cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent), 1205 cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent),
@@ -1207,8 +1218,8 @@ static int io_subchannel_probe(struct subchannel *sch)
1207 } 1218 }
1208 cdev = io_subchannel_create_ccwdev(sch); 1219 cdev = io_subchannel_create_ccwdev(sch);
1209 if (IS_ERR(cdev)) { 1220 if (IS_ERR(cdev)) {
1210 kfree(sch->private); 1221 rc = PTR_ERR(cdev);
1211 return PTR_ERR(cdev); 1222 goto out_err;
1212 } 1223 }
1213 rc = io_subchannel_recog(cdev, sch); 1224 rc = io_subchannel_recog(cdev, sch);
1214 if (rc) { 1225 if (rc) {
@@ -1217,9 +1228,12 @@ static int io_subchannel_probe(struct subchannel *sch)
1217 spin_unlock_irqrestore(sch->lock, flags); 1228 spin_unlock_irqrestore(sch->lock, flags);
1218 if (cdev->dev.release) 1229 if (cdev->dev.release)
1219 cdev->dev.release(&cdev->dev); 1230 cdev->dev.release(&cdev->dev);
1220 kfree(sch->private); 1231 goto out_err;
1221 } 1232 }
1222 1233 return 0;
1234out_err:
1235 kfree(sch->private);
1236 sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
1223 return rc; 1237 return rc;
1224} 1238}
1225 1239
@@ -1240,6 +1254,7 @@ io_subchannel_remove (struct subchannel *sch)
1240 ccw_device_unregister(cdev); 1254 ccw_device_unregister(cdev);
1241 put_device(&cdev->dev); 1255 put_device(&cdev->dev);
1242 kfree(sch->private); 1256 kfree(sch->private);
1257 sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group);
1243 return 0; 1258 return 0;
1244} 1259}
1245 1260