aboutsummaryrefslogtreecommitdiff
path: root/drivers/message/i2o/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/i2o/device.c')
-rw-r--r--drivers/message/i2o/device.c106
1 files changed, 72 insertions, 34 deletions
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 489d7c5c496..98348f420b5 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -52,7 +52,6 @@ static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
/**
* i2o_device_claim - claim a device for use by an OSM
* @dev: I2O device to claim
- * @drv: I2O driver which wants to claim the device
*
* Do the leg work to assign a device to a given OSM. If the claim succeeds,
* the owner is the primary. If the attempt fails a negative errno code
@@ -66,7 +65,7 @@ int i2o_device_claim(struct i2o_device *dev)
rc = i2o_device_issue_claim(dev, I2O_CMD_UTIL_CLAIM, I2O_CLAIM_PRIMARY);
if (!rc)
- pr_debug("i2o: claim of device %d succeded\n",
+ pr_debug("i2o: claim of device %d succeeded\n",
dev->lct_data.tid);
else
pr_debug("i2o: claim of device %d failed %d\n",
@@ -80,7 +79,6 @@ int i2o_device_claim(struct i2o_device *dev)
/**
* i2o_device_claim_release - release a device that the OSM is using
* @dev: device to release
- * @drv: driver which claimed the device
*
* Drop a claim by an OSM on a given I2O device.
*
@@ -112,7 +110,7 @@ int i2o_device_claim_release(struct i2o_device *dev)
}
if (!rc)
- pr_debug("i2o: claim release of device %d succeded\n",
+ pr_debug("i2o: claim release of device %d succeeded\n",
dev->lct_data.tid);
else
pr_debug("i2o: claim release of device %d failed %d\n",
@@ -134,51 +132,61 @@ static void i2o_device_release(struct device *dev)
{
struct i2o_device *i2o_dev = to_i2o_device(dev);
- pr_debug("i2o: device %s released\n", dev->bus_id);
+ pr_debug("i2o: device %s released\n", dev_name(dev));
kfree(i2o_dev);
}
/**
- * i2o_device_show_class_id - Displays class id of I2O device
+ * class_id_show - Displays class id of I2O device
* @dev: device of which the class id should be displayed
* @attr: pointer to device attribute
* @buf: buffer into which the class id should be printed
*
* Returns the number of bytes which are printed into the buffer.
*/
-static ssize_t i2o_device_show_class_id(struct device *dev,
- struct device_attribute *attr,
- char *buf)
+static ssize_t class_id_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct i2o_device *i2o_dev = to_i2o_device(dev);
sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id);
return strlen(buf) + 1;
}
+static DEVICE_ATTR_RO(class_id);
/**
- * i2o_device_show_tid - Displays TID of I2O device
+ * tid_show - Displays TID of I2O device
* @dev: device of which the TID should be displayed
* @attr: pointer to device attribute
* @buf: buffer into which the TID should be printed
*
* Returns the number of bytes which are printed into the buffer.
*/
-static ssize_t i2o_device_show_tid(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t tid_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct i2o_device *i2o_dev = to_i2o_device(dev);
sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid);
return strlen(buf) + 1;
}
+static DEVICE_ATTR_RO(tid);
/* I2O device attributes */
-struct device_attribute i2o_device_attrs[] = {
- __ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
- __ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
- __ATTR_NULL
+static struct attribute *i2o_device_attrs[] = {
+ &dev_attr_class_id.attr,
+ &dev_attr_tid.attr,
+ NULL,
+};
+
+static const struct attribute_group i2o_device_group = {
+ .attrs = i2o_device_attrs,
+};
+
+const struct attribute_group *i2o_device_groups[] = {
+ &i2o_device_group,
+ NULL,
};
/**
@@ -229,8 +237,8 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry)
i2o_dev->lct_data = *entry;
- snprintf(i2o_dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit,
- i2o_dev->lct_data.tid);
+ dev_set_name(&i2o_dev->device, "%d:%03x", c->unit,
+ i2o_dev->lct_data.tid);
i2o_dev->iop = c;
i2o_dev->device.parent = &c->device;
@@ -243,36 +251,66 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry)
/* create user entries for this device */
tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
- if (tmp && (tmp != i2o_dev))
- sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
- "user");
+ if (tmp && (tmp != i2o_dev)) {
+ rc = sysfs_create_link(&i2o_dev->device.kobj,
+ &tmp->device.kobj, "user");
+ if (rc)
+ goto unreg_dev;
+ }
- /* create user entries refering to this device */
+ /* create user entries referring to this device */
list_for_each_entry(tmp, &c->devices, list)
if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
- && (tmp != i2o_dev))
- sysfs_create_link(&tmp->device.kobj,
- &i2o_dev->device.kobj, "user");
+ && (tmp != i2o_dev)) {
+ rc = sysfs_create_link(&tmp->device.kobj,
+ &i2o_dev->device.kobj, "user");
+ if (rc)
+ goto rmlink1;
+ }
/* create parent entries for this device */
tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
- if (tmp && (tmp != i2o_dev))
- sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
- "parent");
+ if (tmp && (tmp != i2o_dev)) {
+ rc = sysfs_create_link(&i2o_dev->device.kobj,
+ &tmp->device.kobj, "parent");
+ if (rc)
+ goto rmlink1;
+ }
- /* create parent entries refering to this device */
+ /* create parent entries referring to this device */
list_for_each_entry(tmp, &c->devices, list)
if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
- && (tmp != i2o_dev))
- sysfs_create_link(&tmp->device.kobj,
- &i2o_dev->device.kobj, "parent");
+ && (tmp != i2o_dev)) {
+ rc = sysfs_create_link(&tmp->device.kobj,
+ &i2o_dev->device.kobj, "parent");
+ if (rc)
+ goto rmlink2;
+ }
i2o_driver_notify_device_add_all(i2o_dev);
- pr_debug("i2o: device %s added\n", i2o_dev->device.bus_id);
+ pr_debug("i2o: device %s added\n", dev_name(&i2o_dev->device));
return 0;
+rmlink2:
+ /* If link creating failed halfway, we loop whole list to cleanup.
+ * And we don't care wrong removing of link, because sysfs_remove_link
+ * will take care of it.
+ */
+ list_for_each_entry(tmp, &c->devices, list) {
+ if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+ sysfs_remove_link(&tmp->device.kobj, "parent");
+ }
+ sysfs_remove_link(&i2o_dev->device.kobj, "parent");
+rmlink1:
+ list_for_each_entry(tmp, &c->devices, list)
+ if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+ sysfs_remove_link(&tmp->device.kobj, "user");
+ sysfs_remove_link(&i2o_dev->device.kobj, "user");
+unreg_dev:
+ list_del(&i2o_dev->list);
+ device_unregister(&i2o_dev->device);
err:
kfree(i2o_dev);
return rc;
@@ -437,7 +475,7 @@ int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
res.virt = NULL;
- if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL))
+ if (i2o_dma_alloc(dev, &res, reslen))
return -ENOMEM;
msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);