提交 a1c1f5ea 编写于 作者: E Einar Lueck 提交者: David S. Miller

ctcm rollback in case of errors

Group device now cleanly reacts to failures during channel start and
implements a clean rollback.
Signed-off-by: NEinar Lueck <elelueck@de.ibm.com>
Signed-off-by: NUrsula Braun <ursula.braun@de.ibm.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 d816d423
......@@ -1530,11 +1530,16 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
struct net_device *dev;
struct ccw_device *cdev0;
struct ccw_device *cdev1;
struct channel *readc;
struct channel *writec;
int ret;
int result;
priv = dev_get_drvdata(&cgdev->dev);
if (!priv)
return -ENODEV;
if (!priv) {
result = -ENODEV;
goto out_err_result;
}
cdev0 = cgdev->cdev[0];
cdev1 = cgdev->cdev[1];
......@@ -1545,31 +1550,40 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
snprintf(write_id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev1->dev));
ret = add_channel(cdev0, type, priv);
if (ret)
return ret;
if (ret) {
result = ret;
goto out_err_result;
}
ret = add_channel(cdev1, type, priv);
if (ret)
return ret;
if (ret) {
result = ret;
goto out_remove_channel1;
}
ret = ccw_device_set_online(cdev0);
if (ret != 0) {
/* may be ok to fail now - can be done later */
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
"%s(%s) set_online rc=%d",
CTCM_FUNTAIL, read_id, ret);
result = -EIO;
goto out_remove_channel2;
}
ret = ccw_device_set_online(cdev1);
if (ret != 0) {
/* may be ok to fail now - can be done later */
CTCM_DBF_TEXT_(TRACE, CTC_DBF_NOTICE,
"%s(%s) set_online rc=%d",
CTCM_FUNTAIL, write_id, ret);
result = -EIO;
goto out_ccw1;
}
dev = ctcm_init_netdevice(priv);
if (dev == NULL)
goto out;
if (dev == NULL) {
result = -ENODEV;
goto out_ccw2;
}
for (direction = READ; direction <= WRITE; direction++) {
priv->channel[direction] =
......@@ -1587,12 +1601,14 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
/* sysfs magic */
SET_NETDEV_DEV(dev, &cgdev->dev);
if (register_netdev(dev))
goto out_dev;
if (register_netdev(dev)) {
result = -ENODEV;
goto out_dev;
}
if (ctcm_add_attributes(&cgdev->dev)) {
unregister_netdev(dev);
goto out_dev;
result = -ENODEV;
goto out_unregister;
}
strlcpy(priv->fsm->name, dev->name, sizeof(priv->fsm->name));
......@@ -1608,13 +1624,22 @@ static int ctcm_new_device(struct ccwgroup_device *cgdev)
priv->channel[WRITE]->id, priv->protocol);
return 0;
out_unregister:
unregister_netdev(dev);
out_dev:
ctcm_free_netdevice(dev);
out:
out_ccw2:
ccw_device_set_offline(cgdev->cdev[1]);
out_ccw1:
ccw_device_set_offline(cgdev->cdev[0]);
return -ENODEV;
out_remove_channel2:
readc = channel_get(type, read_id, READ);
channel_remove(readc);
out_remove_channel1:
writec = channel_get(type, write_id, WRITE);
channel_remove(writec);
out_err_result:
return result;
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册