Commit 9797ead5 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] s390: tape driver fixes.

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

tape driver fixes:
 - Link from ccw device to class device in sysfs.
 - Cosmetic changes.
 - Add copyright statements.
parent ed8e66ba
...@@ -18,6 +18,6 @@ obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o ...@@ -18,6 +18,6 @@ obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o
tape-$(CONFIG_PROC_FS) += tape_proc.o tape-$(CONFIG_PROC_FS) += tape_proc.o
tape-objs := tape_core.o tape_std.o tape_char.o tape_class.o $(tape-y) tape-objs := tape_core.o tape_std.o tape_char.o $(tape-y)
obj-$(CONFIG_S390_TAPE) += tape.o obj-$(CONFIG_S390_TAPE) += tape.o tape_class.o
obj-$(CONFIG_S390_TAPE_34XX) += tape_34xx.o obj-$(CONFIG_S390_TAPE_34XX) += tape_34xx.o
...@@ -199,8 +199,8 @@ struct tape_device { ...@@ -199,8 +199,8 @@ struct tape_device {
struct list_head node; struct list_head node;
struct ccw_device * cdev; struct ccw_device * cdev;
struct cdev * nt; struct tape_class_device * nt;
struct cdev * rt; struct tape_class_device * rt;
/* Device discipline information. */ /* Device discipline information. */
struct tape_discipline * discipline; struct tape_discipline * discipline;
......
...@@ -48,38 +48,29 @@ static struct file_operations tape_fops = ...@@ -48,38 +48,29 @@ static struct file_operations tape_fops =
static int tapechar_major = TAPECHAR_MAJOR; 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 * This function is called for every new tapedevice
*/ */
int int
tapechar_setup_device(struct tape_device * device) tapechar_setup_device(struct tape_device * device)
{ {
device->nt = tapechar_register_tape_dev( char device_name[20];
device,
"ntibm", sprintf(device_name, "ntibm%i", device->first_minor / 2);
device->first_minor 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_name[0] = 'r';
device, device->rt = register_tape_dev(
"rtibm", &device->cdev->dev,
device->first_minor + 1 MKDEV(tapechar_major, device->first_minor + 1),
&tape_fops,
device_name,
"rewinding"
); );
return 0; return 0;
...@@ -500,9 +491,6 @@ tapechar_init (void) ...@@ -500,9 +491,6 @@ tapechar_init (void)
tapechar_major = MAJOR(dev); tapechar_major = MAJOR(dev);
PRINT_INFO("tape gets major %d for character devices\n", MAJOR(dev)); PRINT_INFO("tape gets major %d for character devices\n", MAJOR(dev));
#ifdef TAPE390_INTERNAL_CLASS
tape_setup_class();
#endif
return 0; return 0;
} }
...@@ -512,9 +500,6 @@ tapechar_init (void) ...@@ -512,9 +500,6 @@ tapechar_init (void)
void void
tapechar_exit(void) tapechar_exit(void)
{ {
#ifdef TAPE390_INTERNAL_CLASS
tape_cleanup_class();
#endif
PRINT_INFO("tape releases major %d for character devices\n", PRINT_INFO("tape releases major %d for character devices\n",
tapechar_major); tapechar_major);
unregister_chrdev_region(MKDEV(tapechar_major, 0), 256); unregister_chrdev_region(MKDEV(tapechar_major, 0), 256);
......
/* /*
* (C) Copyright IBM Corp. 2004
* tape_class.c ($Revision: 1.6 $)
*
* Tape class device support * Tape class device support
* *
* Author: Stefan Bader <shbader@de.ibm.com> * Author: Stefan Bader <shbader@de.ibm.com>
...@@ -6,11 +9,12 @@ ...@@ -6,11 +9,12 @@
*/ */
#include "tape_class.h" #include "tape_class.h"
#ifndef TAPE390_INTERNAL_CLASS
MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>"); MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
MODULE_DESCRIPTION("Tape class"); MODULE_DESCRIPTION(
"(C) Copyright IBM Corp. 2004 All Rights Reserved.\n"
"tape_class.c ($Revision: 1.6 $)"
);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#endif
struct class_simple *tape_class; struct class_simple *tape_class;
...@@ -29,69 +33,94 @@ struct class_simple *tape_class; ...@@ -29,69 +33,94 @@ struct class_simple *tape_class;
* devname * devname
* The pointer to the name of the character device. * The pointer to the name of the character device.
*/ */
struct cdev *register_tape_dev( struct tape_class_device *register_tape_dev(
struct device * device, struct device * device,
dev_t dev, dev_t dev,
struct file_operations *fops, struct file_operations *fops,
char * devname char * device_name,
) { char * mode_name)
struct cdev * cdev; {
struct tape_class_device * tcd;
int rc; int rc;
char * s; char * s;
cdev = cdev_alloc(); tcd = kmalloc(sizeof(struct tape_class_device), GFP_KERNEL);
if (!cdev) if (!tcd)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
cdev->owner = fops->owner; memset(tcd, 0, sizeof(struct tape_class_device));
cdev->ops = fops; strncpy(tcd->device_name, device_name, TAPECLASS_NAME_LEN);
cdev->dev = dev; 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); tcd->char_device = cdev_alloc();
if (rc) { if (!tcd->char_device) {
cdev_del(cdev); rc = -ENOMEM;
return ERR_PTR(rc); 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); EXPORT_SYMBOL(register_tape_dev);
void unregister_tape_dev(struct cdev *cdev) void unregister_tape_dev(struct tape_class_device *tcd)
{ {
if (cdev != NULL) { if (tcd != NULL && !IS_ERR(tcd)) {
class_simple_device_remove(cdev->dev); sysfs_remove_link(
cdev_del(cdev); &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); EXPORT_SYMBOL(unregister_tape_dev);
#ifndef TAPE390_INTERNAL_CLASS
static int __init tape_init(void) static int __init tape_init(void)
#else
int tape_setup_class(void)
#endif
{ {
tape_class = class_simple_create(THIS_MODULE, "tape390"); tape_class = class_simple_create(THIS_MODULE, "tape390");
return 0; return 0;
} }
#ifndef TAPE390_INTERNAL_CLASS
static void __exit tape_exit(void) static void __exit tape_exit(void)
#else
void tape_cleanup_class(void)
#endif
{ {
class_simple_destroy(tape_class); class_simple_destroy(tape_class);
tape_class = NULL; tape_class = NULL;
} }
#ifndef TAPE390_INTERNAL_CLASS
postcore_initcall(tape_init); postcore_initcall(tape_init);
module_exit(tape_exit); module_exit(tape_exit);
#else
EXPORT_SYMBOL(tape_setup_class);
EXPORT_SYMBOL(tape_cleanup_class);
#endif
/* /*
* (C) Copyright IBM Corp. 2004 All Rights Reserved.
* tape_class.h ($Revision: 1.4 $)
*
* Tape class device support * Tape class device support
* *
* Author: Stefan Bader <shbader@de.ibm.com> * Author: Stefan Bader <shbader@de.ibm.com>
...@@ -7,11 +10,8 @@ ...@@ -7,11 +10,8 @@
#ifndef __TAPE_CLASS_H__ #ifndef __TAPE_CLASS_H__
#define __TAPE_CLASS_H__ #define __TAPE_CLASS_H__
#if 0
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#endif
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/kobject.h> #include <linux/kobject.h>
...@@ -21,34 +21,41 @@ ...@@ -21,34 +21,41 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#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 * device
* The pointer to the struct device of the physical (base) 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 * dev
* The intended major/minor number. The major number may be 0 to * The intended major/minor number. The major number may be 0 to
* get a dynamic major number. * get a dynamic major number.
* fops * fops
* The pointer to the drivers file operations for the tape device. * The pointer to the drivers file operations for the tape device.
* devname * device_name
* The pointer to the name of the character device. * 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, struct device * device,
dev_t dev, dev_t dev,
struct file_operations *fops, struct file_operations *fops,
char * devname char * device_name,
char * node_name
); );
void unregister_tape_dev(struct cdev *cdev); void unregister_tape_dev(struct tape_class_device *tcd);
#ifdef TAPE390_INTERNAL_CLASS
int tape_setup_class(void);
void tape_cleanup_class(void);
#endif
#endif /* __TAPE_CLASS_H__ */ #endif /* __TAPE_CLASS_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment