diff options
author | Christopher Kenna <cjk@cs.unc.edu> | 2011-01-07 20:46:25 -0500 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2011-01-12 19:29:35 -0500 |
commit | 37eb46be881dde4b405d3d8b48e76b4a8d62ae2c (patch) | |
tree | aab617d44f19114ecc9ea7cf7e1d64ee35430005 /litmus/ftdev.c | |
parent | 7648363e5636bd865aeac3236eb4675f0687eb4a (diff) |
Feather-Trace: register devices with sysfs
This patch implements support for Feather-Trace devices to use the sysfs
file system and, consequently, udev support.
This allows us to allocate major/minor numbers for Feather-Trace
devices dynamically, which is desirable because our old static
allocations tend to create conflicts on modern distributions and/or
when there are many cores.
Diffstat (limited to 'litmus/ftdev.c')
-rw-r--r-- | litmus/ftdev.c | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/litmus/ftdev.c b/litmus/ftdev.c index 51dafaebf8a6..d68d05c6d7dc 100644 --- a/litmus/ftdev.c +++ b/litmus/ftdev.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/cdev.h> | 4 | #include <linux/cdev.h> |
5 | #include <asm/uaccess.h> | 5 | #include <asm/uaccess.h> |
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/device.h> | ||
7 | 8 | ||
8 | #include <litmus/litmus.h> | 9 | #include <litmus/litmus.h> |
9 | #include <litmus/feather_trace.h> | 10 | #include <litmus/feather_trace.h> |
@@ -310,10 +311,11 @@ struct file_operations ftdev_fops = { | |||
310 | }; | 311 | }; |
311 | 312 | ||
312 | 313 | ||
313 | void ftdev_init(struct ftdev* ftdev, struct module* owner) | 314 | void ftdev_init(struct ftdev* ftdev, struct module* owner, const char* name) |
314 | { | 315 | { |
315 | int i; | 316 | int i, error; |
316 | cdev_init(&ftdev->cdev, &ftdev_fops); | 317 | cdev_init(&ftdev->cdev, &ftdev_fops); |
318 | ftdev->name = name; | ||
317 | ftdev->cdev.owner = owner; | 319 | ftdev->cdev.owner = owner; |
318 | ftdev->cdev.ops = &ftdev_fops; | 320 | ftdev->cdev.ops = &ftdev_fops; |
319 | ftdev->minor_cnt = 0; | 321 | ftdev->minor_cnt = 0; |
@@ -326,35 +328,62 @@ void ftdev_init(struct ftdev* ftdev, struct module* owner) | |||
326 | ftdev->alloc = NULL; | 328 | ftdev->alloc = NULL; |
327 | ftdev->free = NULL; | 329 | ftdev->free = NULL; |
328 | ftdev->can_open = NULL; | 330 | ftdev->can_open = NULL; |
331 | |||
332 | ftdev->class = class_create(owner, ftdev->name); | ||
333 | if (IS_ERR(ftdev->class)) { | ||
334 | error = PTR_ERR(ftdev->class); | ||
335 | printk(KERN_WARNING "ftdev(%s): " | ||
336 | "Could not create device class.\n", | ||
337 | name); | ||
338 | } | ||
329 | } | 339 | } |
330 | 340 | ||
331 | int register_ftdev(struct ftdev* ftdev, const char* name, int major) | 341 | int register_ftdev(struct ftdev* ftdev) |
332 | { | 342 | { |
343 | struct device **device; | ||
333 | dev_t trace_dev; | 344 | dev_t trace_dev; |
334 | int error = 0; | 345 | int error = 0, major, i; |
335 | 346 | ||
336 | if(major) { | 347 | error = alloc_chrdev_region(&trace_dev, 0, ftdev->minor_cnt, |
337 | trace_dev = MKDEV(major, 0); | 348 | ftdev->name); |
338 | error = register_chrdev_region(trace_dev, ftdev->minor_cnt, | 349 | major = MAJOR(trace_dev); |
339 | name); | ||
340 | } else { | ||
341 | error = alloc_chrdev_region(&trace_dev, 0, ftdev->minor_cnt, | ||
342 | name); | ||
343 | major = MAJOR(trace_dev); | ||
344 | } | ||
345 | if (error) | 350 | if (error) |
346 | { | 351 | { |
347 | printk(KERN_WARNING "ftdev(%s): " | 352 | printk(KERN_WARNING "ftdev(%s): " |
348 | "Could not register major/minor number %d/%u\n", | 353 | "Could not register major/minor number %d/%u\n", |
349 | name, major, ftdev->minor_cnt); | 354 | ftdev->name, major, ftdev->minor_cnt); |
350 | return error; | 355 | goto out; |
351 | } | 356 | } |
352 | error = cdev_add(&ftdev->cdev, trace_dev, ftdev->minor_cnt); | 357 | error = cdev_add(&ftdev->cdev, trace_dev, ftdev->minor_cnt); |
353 | if (error) { | 358 | if (error) { |
354 | printk(KERN_WARNING "ftdev(%s): " | 359 | printk(KERN_WARNING "ftdev(%s): " |
355 | "Could not add cdev for major/minor = %d/%u.\n", | 360 | "Could not add cdev for major/minor = %d/%u.\n", |
356 | name, major, ftdev->minor_cnt); | 361 | ftdev->name, major, ftdev->minor_cnt); |
357 | return error; | 362 | goto out; |
363 | } | ||
364 | |||
365 | /* | ||
366 | * create all the minor devices | ||
367 | */ | ||
368 | for (i = 0; i < ftdev->minor_cnt; ++i) | ||
369 | { | ||
370 | trace_dev = MKDEV(major, i); | ||
371 | device = &(ftdev->minor[i].device); | ||
372 | |||
373 | *device = device_create(ftdev->class, NULL, trace_dev, NULL, | ||
374 | "%s%d", ftdev->name, i); | ||
375 | if (IS_ERR(*device)) { | ||
376 | error = PTR_ERR(*device); | ||
377 | printk(KERN_WARNING "ftdev(%s): " | ||
378 | "Could not create device major/minor number " | ||
379 | "%d/%d\n", ftdev->name, major, i); | ||
380 | printk(KERN_WARNING "ftdev(%s): " | ||
381 | "Will not continue creating devices. Tracing " | ||
382 | "may be in an inconsistent state.\n", | ||
383 | ftdev->name); | ||
384 | goto out; | ||
385 | } | ||
358 | } | 386 | } |
387 | out: | ||
359 | return error; | 388 | return error; |
360 | } | 389 | } |