diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/s390/char/tape_class.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/s390/char/tape_class.c')
-rw-r--r-- | drivers/s390/char/tape_class.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c new file mode 100644 index 000000000000..0f8ffd4167ca --- /dev/null +++ b/drivers/s390/char/tape_class.c | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * (C) Copyright IBM Corp. 2004 | ||
3 | * tape_class.c ($Revision: 1.8 $) | ||
4 | * | ||
5 | * Tape class device support | ||
6 | * | ||
7 | * Author: Stefan Bader <shbader@de.ibm.com> | ||
8 | * Based on simple class device code by Greg K-H | ||
9 | */ | ||
10 | #include "tape_class.h" | ||
11 | |||
12 | MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>"); | ||
13 | MODULE_DESCRIPTION( | ||
14 | "(C) Copyright IBM Corp. 2004 All Rights Reserved.\n" | ||
15 | "tape_class.c ($Revision: 1.8 $)" | ||
16 | ); | ||
17 | MODULE_LICENSE("GPL"); | ||
18 | |||
19 | struct class_simple *tape_class; | ||
20 | |||
21 | /* | ||
22 | * Register a tape device and return a pointer to the cdev structure. | ||
23 | * | ||
24 | * device | ||
25 | * The pointer to the struct device of the physical (base) device. | ||
26 | * drivername | ||
27 | * The pointer to the drivers name for it's character devices. | ||
28 | * dev | ||
29 | * The intended major/minor number. The major number may be 0 to | ||
30 | * get a dynamic major number. | ||
31 | * fops | ||
32 | * The pointer to the drivers file operations for the tape device. | ||
33 | * devname | ||
34 | * The pointer to the name of the character device. | ||
35 | */ | ||
36 | struct tape_class_device *register_tape_dev( | ||
37 | struct device * device, | ||
38 | dev_t dev, | ||
39 | struct file_operations *fops, | ||
40 | char * device_name, | ||
41 | char * mode_name) | ||
42 | { | ||
43 | struct tape_class_device * tcd; | ||
44 | int rc; | ||
45 | char * s; | ||
46 | |||
47 | tcd = kmalloc(sizeof(struct tape_class_device), GFP_KERNEL); | ||
48 | if (!tcd) | ||
49 | return ERR_PTR(-ENOMEM); | ||
50 | |||
51 | memset(tcd, 0, sizeof(struct tape_class_device)); | ||
52 | strncpy(tcd->device_name, device_name, TAPECLASS_NAME_LEN); | ||
53 | for (s = strchr(tcd->device_name, '/'); s; s = strchr(s, '/')) | ||
54 | *s = '!'; | ||
55 | strncpy(tcd->mode_name, mode_name, TAPECLASS_NAME_LEN); | ||
56 | for (s = strchr(tcd->mode_name, '/'); s; s = strchr(s, '/')) | ||
57 | *s = '!'; | ||
58 | |||
59 | tcd->char_device = cdev_alloc(); | ||
60 | if (!tcd->char_device) { | ||
61 | rc = -ENOMEM; | ||
62 | goto fail_with_tcd; | ||
63 | } | ||
64 | |||
65 | tcd->char_device->owner = fops->owner; | ||
66 | tcd->char_device->ops = fops; | ||
67 | tcd->char_device->dev = dev; | ||
68 | |||
69 | rc = cdev_add(tcd->char_device, tcd->char_device->dev, 1); | ||
70 | if (rc) | ||
71 | goto fail_with_cdev; | ||
72 | |||
73 | tcd->class_device = class_simple_device_add( | ||
74 | tape_class, | ||
75 | tcd->char_device->dev, | ||
76 | device, | ||
77 | "%s", tcd->device_name | ||
78 | ); | ||
79 | sysfs_create_link( | ||
80 | &device->kobj, | ||
81 | &tcd->class_device->kobj, | ||
82 | tcd->mode_name | ||
83 | ); | ||
84 | |||
85 | return tcd; | ||
86 | |||
87 | fail_with_cdev: | ||
88 | cdev_del(tcd->char_device); | ||
89 | |||
90 | fail_with_tcd: | ||
91 | kfree(tcd); | ||
92 | |||
93 | return ERR_PTR(rc); | ||
94 | } | ||
95 | EXPORT_SYMBOL(register_tape_dev); | ||
96 | |||
97 | void unregister_tape_dev(struct tape_class_device *tcd) | ||
98 | { | ||
99 | if (tcd != NULL && !IS_ERR(tcd)) { | ||
100 | sysfs_remove_link( | ||
101 | &tcd->class_device->dev->kobj, | ||
102 | tcd->mode_name | ||
103 | ); | ||
104 | class_simple_device_remove(tcd->char_device->dev); | ||
105 | cdev_del(tcd->char_device); | ||
106 | kfree(tcd); | ||
107 | } | ||
108 | } | ||
109 | EXPORT_SYMBOL(unregister_tape_dev); | ||
110 | |||
111 | |||
112 | static int __init tape_init(void) | ||
113 | { | ||
114 | tape_class = class_simple_create(THIS_MODULE, "tape390"); | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static void __exit tape_exit(void) | ||
120 | { | ||
121 | class_simple_destroy(tape_class); | ||
122 | tape_class = NULL; | ||
123 | } | ||
124 | |||
125 | postcore_initcall(tape_init); | ||
126 | module_exit(tape_exit); | ||