From 9797ead56840ca990be6de904f4c3e390230039e Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 16 Mar 2004 15:08:48 -0800 Subject: [PATCH] [PATCH] s390: tape driver fixes. From: Martin Schwidefsky tape driver fixes: - Link from ccw device to class device in sysfs. - Cosmetic changes. - Add copyright statements. --- drivers/s390/char/Makefile | 4 +- drivers/s390/char/tape.h | 4 +- drivers/s390/char/tape_char.c | 47 ++++++---------- drivers/s390/char/tape_class.c | 99 ++++++++++++++++++++++------------ drivers/s390/char/tape_class.h | 41 ++++++++------ 5 files changed, 108 insertions(+), 87 deletions(-) diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 3e48c4faddcdd..6aa04e76fc8e7 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile @@ -18,6 +18,6 @@ obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o tape-$(CONFIG_PROC_FS) += tape_proc.o -tape-objs := tape_core.o tape_std.o tape_char.o tape_class.o $(tape-y) -obj-$(CONFIG_S390_TAPE) += tape.o +tape-objs := tape_core.o tape_std.o tape_char.o $(tape-y) +obj-$(CONFIG_S390_TAPE) += tape.o tape_class.o obj-$(CONFIG_S390_TAPE_34XX) += tape_34xx.o diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 10f9eb4126389..945ee03956ec7 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -199,8 +199,8 @@ struct tape_device { struct list_head node; struct ccw_device * cdev; - struct cdev * nt; - struct cdev * rt; + struct tape_class_device * nt; + struct tape_class_device * rt; /* Device discipline information. */ struct tape_discipline * discipline; diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 8596025fd248f..ccbe214d75b17 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c @@ -48,38 +48,29 @@ static struct file_operations tape_fops = static int tapechar_major = TAPECHAR_MAJOR; -struct cdev * -tapechar_register_tape_dev(struct tape_device *device, char *name, int i) -{ - struct cdev * cdev; - char devname[11]; - - sprintf(devname, "%s%i", name, i / 2); - cdev = register_tape_dev( - &device->cdev->dev, - MKDEV(tapechar_major, i), - &tape_fops, - devname - ); - - return ((IS_ERR(cdev)) ? NULL : cdev); -} - /* * This function is called for every new tapedevice */ int tapechar_setup_device(struct tape_device * device) { - device->nt = tapechar_register_tape_dev( - device, - "ntibm", - device->first_minor + char device_name[20]; + + sprintf(device_name, "ntibm%i", device->first_minor / 2); + device->nt = register_tape_dev( + &device->cdev->dev, + MKDEV(tapechar_major, device->first_minor), + &tape_fops, + device_name, + "non-rewinding" ); - device->rt = tapechar_register_tape_dev( - device, - "rtibm", - device->first_minor + 1 + device_name[0] = 'r'; + device->rt = register_tape_dev( + &device->cdev->dev, + MKDEV(tapechar_major, device->first_minor + 1), + &tape_fops, + device_name, + "rewinding" ); return 0; @@ -500,9 +491,6 @@ tapechar_init (void) tapechar_major = MAJOR(dev); PRINT_INFO("tape gets major %d for character devices\n", MAJOR(dev)); -#ifdef TAPE390_INTERNAL_CLASS - tape_setup_class(); -#endif return 0; } @@ -512,9 +500,6 @@ tapechar_init (void) void tapechar_exit(void) { -#ifdef TAPE390_INTERNAL_CLASS - tape_cleanup_class(); -#endif PRINT_INFO("tape releases major %d for character devices\n", tapechar_major); unregister_chrdev_region(MKDEV(tapechar_major, 0), 256); diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index 6ebae2022b190..85f1693879cc5 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -1,4 +1,7 @@ /* + * (C) Copyright IBM Corp. 2004 + * tape_class.c ($Revision: 1.6 $) + * * Tape class device support * * Author: Stefan Bader @@ -6,11 +9,12 @@ */ #include "tape_class.h" -#ifndef TAPE390_INTERNAL_CLASS MODULE_AUTHOR("Stefan Bader "); -MODULE_DESCRIPTION("Tape class"); +MODULE_DESCRIPTION( + "(C) Copyright IBM Corp. 2004 All Rights Reserved.\n" + "tape_class.c ($Revision: 1.6 $)" +); MODULE_LICENSE("GPL"); -#endif struct class_simple *tape_class; @@ -29,69 +33,94 @@ struct class_simple *tape_class; * devname * The pointer to the name of the character device. */ -struct cdev *register_tape_dev( +struct tape_class_device *register_tape_dev( struct device * device, dev_t dev, struct file_operations *fops, - char * devname -) { - struct cdev * cdev; + char * device_name, + char * mode_name) +{ + struct tape_class_device * tcd; int rc; char * s; - cdev = cdev_alloc(); - if (!cdev) + tcd = kmalloc(sizeof(struct tape_class_device), GFP_KERNEL); + if (!tcd) return ERR_PTR(-ENOMEM); - cdev->owner = fops->owner; - cdev->ops = fops; - cdev->dev = dev; + memset(tcd, 0, sizeof(struct tape_class_device)); + strncpy(tcd->device_name, device_name, TAPECLASS_NAME_LEN); + for (s = strchr(tcd->device_name, '/'); s; s = strchr(s, '/')) + *s = '!'; + strncpy(tcd->mode_name, mode_name, TAPECLASS_NAME_LEN); + for (s = strchr(tcd->mode_name, '/'); s; s = strchr(s, '/')) + *s = '!'; - rc = cdev_add(cdev, cdev->dev, 1); - if (rc) { - cdev_del(cdev); - return ERR_PTR(rc); + tcd->char_device = cdev_alloc(); + if (!tcd->char_device) { + rc = -ENOMEM; + goto fail_with_tcd; } - class_simple_device_add(tape_class, cdev->dev, device, "%s", devname); - return cdev; + tcd->char_device->owner = fops->owner; + tcd->char_device->ops = fops; + tcd->char_device->dev = dev; + + rc = cdev_add(tcd->char_device, tcd->char_device->dev, 1); + if (rc) + goto fail_with_cdev; + + tcd->class_device = class_simple_device_add( + tape_class, + tcd->char_device->dev, + device, + "%s", tcd->device_name + ); + sysfs_create_link( + &device->kobj, + &tcd->class_device->kobj, + tcd->mode_name + ); + + return tcd; + +fail_with_cdev: + cdev_del(&tcd->char_device); + +fail_with_tcd: + kfree(tcd); + + return ERR_PTR(rc); } EXPORT_SYMBOL(register_tape_dev); -void unregister_tape_dev(struct cdev *cdev) +void unregister_tape_dev(struct tape_class_device *tcd) { - if (cdev != NULL) { - class_simple_device_remove(cdev->dev); - cdev_del(cdev); + if (tcd != NULL && !IS_ERR(tcd)) { + sysfs_remove_link( + &tcd->class_device->dev->kobj, + tcd->mode_name + ); + class_simple_device_remove(tcd->char_device->dev); + cdev_del(tcd->char_device); + kfree(tcd); } } EXPORT_SYMBOL(unregister_tape_dev); -#ifndef TAPE390_INTERNAL_CLASS static int __init tape_init(void) -#else -int tape_setup_class(void) -#endif { tape_class = class_simple_create(THIS_MODULE, "tape390"); + return 0; } -#ifndef TAPE390_INTERNAL_CLASS static void __exit tape_exit(void) -#else -void tape_cleanup_class(void) -#endif { class_simple_destroy(tape_class); tape_class = NULL; } -#ifndef TAPE390_INTERNAL_CLASS postcore_initcall(tape_init); module_exit(tape_exit); -#else -EXPORT_SYMBOL(tape_setup_class); -EXPORT_SYMBOL(tape_cleanup_class); -#endif diff --git a/drivers/s390/char/tape_class.h b/drivers/s390/char/tape_class.h index 04fbb7de6cf02..33133ad00ba21 100644 --- a/drivers/s390/char/tape_class.h +++ b/drivers/s390/char/tape_class.h @@ -1,4 +1,7 @@ /* + * (C) Copyright IBM Corp. 2004 All Rights Reserved. + * tape_class.h ($Revision: 1.4 $) + * * Tape class device support * * Author: Stefan Bader @@ -7,11 +10,8 @@ #ifndef __TAPE_CLASS_H__ #define __TAPE_CLASS_H__ -#if 0 #include #include -#endif - #include #include #include @@ -21,34 +21,41 @@ #include #include -#define TAPE390_INTERNAL_CLASS +#define TAPECLASS_NAME_LEN 32 + +struct tape_class_device { + struct cdev * char_device; + struct class_device * class_device; + char device_name[TAPECLASS_NAME_LEN]; + char mode_name[TAPECLASS_NAME_LEN]; +}; /* - * Register a tape device and return a pointer to the cdev structure. + * Register a tape device and return a pointer to the tape class device + * created by the call. * * device * The pointer to the struct device of the physical (base) device. - * drivername - * The pointer to the drivers name for it's character devices. * dev * The intended major/minor number. The major number may be 0 to * get a dynamic major number. * fops * The pointer to the drivers file operations for the tape device. - * devname - * The pointer to the name of the character device. + * device_name + * Pointer to the logical device name (will also be used as kobject name + * of the cdev). This can also be called the name of the tape class + * device. + * mode_name + * Points to the name of the tape mode. This creates a link with that + * name from the physical device to the logical device (class). */ -struct cdev *register_tape_dev( +struct tape_class_device *register_tape_dev( struct device * device, dev_t dev, struct file_operations *fops, - char * devname + char * device_name, + char * node_name ); -void unregister_tape_dev(struct cdev *cdev); - -#ifdef TAPE390_INTERNAL_CLASS -int tape_setup_class(void); -void tape_cleanup_class(void); -#endif +void unregister_tape_dev(struct tape_class_device *tcd); #endif /* __TAPE_CLASS_H__ */ -- 2.53.0