0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define KMSG_COMPONENT "tape"
0012 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0013
0014 #include <linux/slab.h>
0015
0016 #include "tape_class.h"
0017
0018 MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
0019 MODULE_DESCRIPTION(
0020 "Copyright IBM Corp. 2004 All Rights Reserved.\n"
0021 "tape_class.c"
0022 );
0023 MODULE_LICENSE("GPL");
0024
0025 static struct class *tape_class;
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 struct tape_class_device *register_tape_dev(
0043 struct device * device,
0044 dev_t dev,
0045 const struct file_operations *fops,
0046 char * device_name,
0047 char * mode_name)
0048 {
0049 struct tape_class_device * tcd;
0050 int rc;
0051 char * s;
0052
0053 tcd = kzalloc(sizeof(struct tape_class_device), GFP_KERNEL);
0054 if (!tcd)
0055 return ERR_PTR(-ENOMEM);
0056
0057 strlcpy(tcd->device_name, device_name, TAPECLASS_NAME_LEN);
0058 for (s = strchr(tcd->device_name, '/'); s; s = strchr(s, '/'))
0059 *s = '!';
0060 strlcpy(tcd->mode_name, mode_name, TAPECLASS_NAME_LEN);
0061 for (s = strchr(tcd->mode_name, '/'); s; s = strchr(s, '/'))
0062 *s = '!';
0063
0064 tcd->char_device = cdev_alloc();
0065 if (!tcd->char_device) {
0066 rc = -ENOMEM;
0067 goto fail_with_tcd;
0068 }
0069
0070 tcd->char_device->owner = fops->owner;
0071 tcd->char_device->ops = fops;
0072
0073 rc = cdev_add(tcd->char_device, dev, 1);
0074 if (rc)
0075 goto fail_with_cdev;
0076
0077 tcd->class_device = device_create(tape_class, device,
0078 tcd->char_device->dev, NULL,
0079 "%s", tcd->device_name);
0080 rc = PTR_ERR_OR_ZERO(tcd->class_device);
0081 if (rc)
0082 goto fail_with_cdev;
0083 rc = sysfs_create_link(
0084 &device->kobj,
0085 &tcd->class_device->kobj,
0086 tcd->mode_name
0087 );
0088 if (rc)
0089 goto fail_with_class_device;
0090
0091 return tcd;
0092
0093 fail_with_class_device:
0094 device_destroy(tape_class, tcd->char_device->dev);
0095
0096 fail_with_cdev:
0097 cdev_del(tcd->char_device);
0098
0099 fail_with_tcd:
0100 kfree(tcd);
0101
0102 return ERR_PTR(rc);
0103 }
0104 EXPORT_SYMBOL(register_tape_dev);
0105
0106 void unregister_tape_dev(struct device *device, struct tape_class_device *tcd)
0107 {
0108 if (tcd != NULL && !IS_ERR(tcd)) {
0109 sysfs_remove_link(&device->kobj, tcd->mode_name);
0110 device_destroy(tape_class, tcd->char_device->dev);
0111 cdev_del(tcd->char_device);
0112 kfree(tcd);
0113 }
0114 }
0115 EXPORT_SYMBOL(unregister_tape_dev);
0116
0117
0118 static int __init tape_init(void)
0119 {
0120 tape_class = class_create(THIS_MODULE, "tape390");
0121
0122 return 0;
0123 }
0124
0125 static void __exit tape_exit(void)
0126 {
0127 class_destroy(tape_class);
0128 tape_class = NULL;
0129 }
0130
0131 postcore_initcall(tape_init);
0132 module_exit(tape_exit);