summaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device.c
diff options
context:
space:
mode:
authorCornelia Huck <cohuck@de.ibm.com>2006-01-06 00:19:25 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 08:33:52 -0800
commitfb6958a594da49ece869793e6ec163b89fc5f79f (patch)
tree0746cc23ab13a059f9a34d7fc134aaf6410d07b8 /drivers/s390/cio/device.c
parent678a395b356a98368a93c3640252502b70c3676f (diff)
[PATCH] s390: multiple subchannel sets support
Add support for multiple subchannel sets. Works with arbitrary devices in subchannel set 1 and is transparent to device drivers. Although currently only two subchannel sets are available, this will work with the architectured maximum number of subchannel sets as well. Signed-off-by: Cornelia Huck <cohuck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390/cio/device.c')
-rw-r--r--drivers/s390/cio/device.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index ba9f7c11f63..fa3e4c0a253 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -535,7 +535,8 @@ ccw_device_register(struct ccw_device *cdev)
}
struct match_data {
- unsigned int devno;
+ unsigned int devno;
+ unsigned int ssid;
struct ccw_device * sibling;
};
@@ -548,6 +549,7 @@ match_devno(struct device * dev, void * data)
cdev = to_ccwdev(dev);
if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
(cdev->private->devno == d->devno) &&
+ (cdev->private->ssid == d->ssid) &&
(cdev != d->sibling)) {
cdev->private->state = DEV_STATE_NOT_OPER;
return 1;
@@ -556,11 +558,13 @@ match_devno(struct device * dev, void * data)
}
static struct ccw_device *
-get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
+get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid,
+ struct ccw_device *sibling)
{
struct device *dev;
struct match_data data = {
- .devno = devno,
+ .devno = devno,
+ .ssid = ssid,
.sibling = sibling,
};
@@ -616,7 +620,7 @@ ccw_device_do_unreg_rereg(void *data)
need_rename = 1;
other_cdev = get_disc_ccwdev_by_devno(sch->schib.pmcw.dev,
- cdev);
+ sch->schid.ssid, cdev);
if (other_cdev) {
struct subchannel *other_sch;
@@ -639,8 +643,8 @@ ccw_device_do_unreg_rereg(void *data)
if (test_and_clear_bit(1, &cdev->private->registered))
device_del(&cdev->dev);
if (need_rename)
- snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.0.%04x",
- sch->schib.pmcw.dev);
+ snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
+ sch->schid.ssid, sch->schib.pmcw.dev);
PREPARE_WORK(&cdev->private->kick_work,
ccw_device_add_changed, (void *)cdev);
queue_work(ccw_device_work, &cdev->private->kick_work);
@@ -769,9 +773,11 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
sch->dev.driver_data = cdev;
sch->driver = &io_subchannel_driver;
cdev->ccwlock = &sch->lock;
+
/* Init private data. */
priv = cdev->private;
priv->devno = sch->schib.pmcw.dev;
+ priv->ssid = sch->schid.ssid;
priv->sch_no = sch->schid.sch_no;
priv->state = DEV_STATE_NOT_OPER;
INIT_LIST_HEAD(&priv->cmb_list);
@@ -779,8 +785,8 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
init_timer(&priv->timer);
/* Set an initial name for the device. */
- snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.0.%04x",
- sch->schib.pmcw.dev);
+ snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
+ sch->schid.ssid, sch->schib.pmcw.dev);
/* Increase counter of devices currently in recognition. */
atomic_inc(&ccw_device_init_count);