diff options
| author | Michael Ellerman <michael@ellerman.id.au> | 2005-08-31 21:29:20 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-31 22:42:46 -0400 |
| commit | 76812d81238cda5c5c4060da27517a08287620fc (patch) | |
| tree | 461d70f89c14cfc4586729ad082c92cee3306f4e | |
| parent | db5e8718eac0b8166d6fd05b1ed7f8114c243988 (diff) | |
[PATCH] iseries_veth: Add sysfs support for connection structs
To aid in field debugging, add sysfs support for iseries_veth's connection
structures. At the moment this is all read-only, however we could think about
adding write support for some attributes in future.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
| -rw-r--r-- | drivers/net/iseries_veth.c | 94 |
1 files changed, 90 insertions, 4 deletions
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index b945bf02d257..25481ea67474 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
| @@ -182,10 +182,6 @@ static void veth_release_connection(struct kobject *kobject); | |||
| 182 | static void veth_timed_ack(unsigned long ptr); | 182 | static void veth_timed_ack(unsigned long ptr); |
| 183 | static void veth_timed_reset(unsigned long ptr); | 183 | static void veth_timed_reset(unsigned long ptr); |
| 184 | 184 | ||
| 185 | static struct kobj_type veth_lpar_connection_ktype = { | ||
| 186 | .release = veth_release_connection | ||
| 187 | }; | ||
| 188 | |||
| 189 | /* | 185 | /* |
| 190 | * Utility functions | 186 | * Utility functions |
| 191 | */ | 187 | */ |
| @@ -280,6 +276,81 @@ static int veth_allocate_events(HvLpIndex rlp, int number) | |||
| 280 | } | 276 | } |
| 281 | 277 | ||
| 282 | /* | 278 | /* |
| 279 | * sysfs support | ||
| 280 | */ | ||
| 281 | |||
| 282 | struct veth_cnx_attribute { | ||
| 283 | struct attribute attr; | ||
| 284 | ssize_t (*show)(struct veth_lpar_connection *, char *buf); | ||
| 285 | ssize_t (*store)(struct veth_lpar_connection *, const char *buf); | ||
| 286 | }; | ||
| 287 | |||
| 288 | static ssize_t veth_cnx_attribute_show(struct kobject *kobj, | ||
| 289 | struct attribute *attr, char *buf) | ||
| 290 | { | ||
| 291 | struct veth_cnx_attribute *cnx_attr; | ||
| 292 | struct veth_lpar_connection *cnx; | ||
| 293 | |||
| 294 | cnx_attr = container_of(attr, struct veth_cnx_attribute, attr); | ||
| 295 | cnx = container_of(kobj, struct veth_lpar_connection, kobject); | ||
| 296 | |||
| 297 | if (!cnx_attr->show) | ||
| 298 | return -EIO; | ||
| 299 | |||
| 300 | return cnx_attr->show(cnx, buf); | ||
| 301 | } | ||
| 302 | |||
| 303 | #define CUSTOM_CNX_ATTR(_name, _format, _expression) \ | ||
| 304 | static ssize_t _name##_show(struct veth_lpar_connection *cnx, char *buf)\ | ||
| 305 | { \ | ||
| 306 | return sprintf(buf, _format, _expression); \ | ||
| 307 | } \ | ||
| 308 | struct veth_cnx_attribute veth_cnx_attr_##_name = __ATTR_RO(_name) | ||
| 309 | |||
| 310 | #define SIMPLE_CNX_ATTR(_name) \ | ||
| 311 | CUSTOM_CNX_ATTR(_name, "%lu\n", (unsigned long)cnx->_name) | ||
| 312 | |||
| 313 | SIMPLE_CNX_ATTR(outstanding_tx); | ||
| 314 | SIMPLE_CNX_ATTR(remote_lp); | ||
| 315 | SIMPLE_CNX_ATTR(num_events); | ||
| 316 | SIMPLE_CNX_ATTR(src_inst); | ||
| 317 | SIMPLE_CNX_ATTR(dst_inst); | ||
| 318 | SIMPLE_CNX_ATTR(num_pending_acks); | ||
| 319 | SIMPLE_CNX_ATTR(num_ack_events); | ||
| 320 | CUSTOM_CNX_ATTR(ack_timeout, "%d\n", jiffies_to_msecs(cnx->ack_timeout)); | ||
| 321 | CUSTOM_CNX_ATTR(reset_timeout, "%d\n", jiffies_to_msecs(cnx->reset_timeout)); | ||
| 322 | CUSTOM_CNX_ATTR(state, "0x%.4lX\n", cnx->state); | ||
| 323 | CUSTOM_CNX_ATTR(last_contact, "%d\n", cnx->last_contact ? | ||
| 324 | jiffies_to_msecs(jiffies - cnx->last_contact) : 0); | ||
| 325 | |||
| 326 | #define GET_CNX_ATTR(_name) (&veth_cnx_attr_##_name.attr) | ||
| 327 | |||
| 328 | static struct attribute *veth_cnx_default_attrs[] = { | ||
| 329 | GET_CNX_ATTR(outstanding_tx), | ||
| 330 | GET_CNX_ATTR(remote_lp), | ||
| 331 | GET_CNX_ATTR(num_events), | ||
| 332 | GET_CNX_ATTR(reset_timeout), | ||
| 333 | GET_CNX_ATTR(last_contact), | ||
| 334 | GET_CNX_ATTR(state), | ||
| 335 | GET_CNX_ATTR(src_inst), | ||
| 336 | GET_CNX_ATTR(dst_inst), | ||
| 337 | GET_CNX_ATTR(num_pending_acks), | ||
| 338 | GET_CNX_ATTR(num_ack_events), | ||
| 339 | GET_CNX_ATTR(ack_timeout), | ||
| 340 | NULL | ||
| 341 | }; | ||
| 342 | |||
| 343 | static struct sysfs_ops veth_cnx_sysfs_ops = { | ||
| 344 | .show = veth_cnx_attribute_show | ||
| 345 | }; | ||
| 346 | |||
| 347 | static struct kobj_type veth_lpar_connection_ktype = { | ||
| 348 | .release = veth_release_connection, | ||
| 349 | .sysfs_ops = &veth_cnx_sysfs_ops, | ||
| 350 | .default_attrs = veth_cnx_default_attrs | ||
| 351 | }; | ||
| 352 | |||
| 353 | /* | ||
| 283 | * LPAR connection code | 354 | * LPAR connection code |
| 284 | */ | 355 | */ |
| 285 | 356 | ||
| @@ -1493,6 +1564,8 @@ void __exit veth_module_cleanup(void) | |||
| 1493 | if (!cnx) | 1564 | if (!cnx) |
| 1494 | continue; | 1565 | continue; |
| 1495 | 1566 | ||
| 1567 | /* Remove the connection from sysfs */ | ||
| 1568 | kobject_del(&cnx->kobject); | ||
| 1496 | /* Drop the driver's reference to the connection */ | 1569 | /* Drop the driver's reference to the connection */ |
| 1497 | kobject_put(&cnx->kobject); | 1570 | kobject_put(&cnx->kobject); |
| 1498 | } | 1571 | } |
| @@ -1523,6 +1596,19 @@ int __init veth_module_init(void) | |||
| 1523 | if (rc != 0) | 1596 | if (rc != 0) |
| 1524 | goto error; | 1597 | goto error; |
| 1525 | 1598 | ||
| 1599 | for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) { | ||
| 1600 | struct kobject *kobj; | ||
| 1601 | |||
| 1602 | if (!veth_cnx[i]) | ||
| 1603 | continue; | ||
| 1604 | |||
| 1605 | kobj = &veth_cnx[i]->kobject; | ||
| 1606 | kobj->parent = &veth_driver.driver.kobj; | ||
| 1607 | /* If the add failes, complain but otherwise continue */ | ||
| 1608 | if (0 != kobject_add(kobj)) | ||
| 1609 | veth_error("cnx %d: Failed adding to sysfs.\n", i); | ||
| 1610 | } | ||
| 1611 | |||
| 1526 | return 0; | 1612 | return 0; |
| 1527 | 1613 | ||
| 1528 | error: | 1614 | error: |
