aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.de>2012-08-18 15:20:40 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-14 12:59:29 -0400
commit26898afd67dfd707aa291648ca731063c8333c7f (patch)
treee4cc7b2d58df67319c90995e9deeb847669ca046 /drivers/scsi
parent6c648d95a6af4a79241a916871df17c84c68ea20 (diff)
[SCSI] st: clean up device file creation and removal
This patch cleans up the st device file creation and removal. Reviewed-by: Lee Duncan <lduncan@suse.com> Signed-off-by: Jeff Mahoney <jeffm@suse.com> Acked-by: Kai Mäkisara <kai.makisara@kolumbus.fi> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/st.c195
-rw-r--r--drivers/scsi/st.h1
2 files changed, 91 insertions, 105 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 052622fdba02..ceca095e5d8d 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -193,7 +193,6 @@ static int st_remove(struct device *);
193 193
194static int do_create_sysfs_files(void); 194static int do_create_sysfs_files(void);
195static void do_remove_sysfs_files(void); 195static void do_remove_sysfs_files(void);
196static int do_create_class_files(struct scsi_tape *, int, int);
197 196
198static struct scsi_driver st_template = { 197static struct scsi_driver st_template = {
199 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
@@ -3990,16 +3989,98 @@ static const struct file_operations st_fops =
3990 .llseek = noop_llseek, 3989 .llseek = noop_llseek,
3991}; 3990};
3992 3991
3992static int create_one_cdev(struct scsi_tape *tape, int mode, int rew)
3993{
3994 int i, error;
3995 dev_t cdev_devno;
3996 struct cdev *cdev;
3997 struct device *dev;
3998 struct st_modedef *STm = &(tape->modes[mode]);
3999 char name[10];
4000 int dev_num = tape->index;
4001
4002 cdev_devno = MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, rew));
4003
4004 cdev = cdev_alloc();
4005 if (!cdev) {
4006 pr_err("st%d: out of memory. Device not attached.\n", dev_num);
4007 error = -ENOMEM;
4008 goto out;
4009 }
4010 cdev->owner = THIS_MODULE;
4011 cdev->ops = &st_fops;
4012
4013 error = cdev_add(cdev, cdev_devno, 1);
4014 if (error) {
4015 pr_err("st%d: Can't add %s-rewind mode %d\n", dev_num,
4016 rew ? "non" : "auto", mode);
4017 pr_err("st%d: Device not attached.\n", dev_num);
4018 goto out_free;
4019 }
4020 STm->cdevs[rew] = cdev;
4021
4022 i = mode << (4 - ST_NBR_MODE_BITS);
4023 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4024 tape->disk->disk_name, st_formats[i]);
4025
4026 dev = device_create(&st_sysfs_class, &tape->device->sdev_gendev,
4027 cdev_devno, &tape->modes[mode], "%s", name);
4028 if (IS_ERR(dev)) {
4029 pr_err("st%d: device_create failed\n", dev_num);
4030 error = PTR_ERR(dev);
4031 goto out_free;
4032 }
4033
4034 STm->devs[rew] = dev;
4035
4036 return 0;
4037out_free:
4038 cdev_del(STm->cdevs[rew]);
4039 STm->cdevs[rew] = NULL;
4040out:
4041 return error;
4042}
4043
4044static int create_cdevs(struct scsi_tape *tape)
4045{
4046 int mode, error;
4047 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4048 error = create_one_cdev(tape, mode, 0);
4049 if (error)
4050 return error;
4051 error = create_one_cdev(tape, mode, 1);
4052 if (error)
4053 return error;
4054 }
4055
4056 return sysfs_create_link(&tape->device->sdev_gendev.kobj,
4057 &tape->modes[0].devs[0]->kobj, "tape");
4058}
4059
4060static void remove_cdevs(struct scsi_tape *tape)
4061{
4062 int mode, rew;
4063 sysfs_remove_link(&tape->device->sdev_gendev.kobj, "tape");
4064 for (mode = 0; mode < ST_NBR_MODES; mode++) {
4065 struct st_modedef *STm = &(tape->modes[mode]);
4066 for (rew = 0; rew < 2; rew++) {
4067 if (STm->cdevs[rew])
4068 cdev_del(STm->cdevs[rew]);
4069 if (STm->devs[rew])
4070 device_unregister(STm->devs[rew]);
4071 }
4072 }
4073}
4074
3993static int st_probe(struct device *dev) 4075static int st_probe(struct device *dev)
3994{ 4076{
3995 struct scsi_device *SDp = to_scsi_device(dev); 4077 struct scsi_device *SDp = to_scsi_device(dev);
3996 struct gendisk *disk = NULL; 4078 struct gendisk *disk = NULL;
3997 struct cdev *cdev = NULL;
3998 struct scsi_tape *tpnt = NULL; 4079 struct scsi_tape *tpnt = NULL;
3999 struct st_modedef *STm; 4080 struct st_modedef *STm;
4000 struct st_partstat *STps; 4081 struct st_partstat *STps;
4001 struct st_buffer *buffer; 4082 struct st_buffer *buffer;
4002 int i, j, mode, dev_num, error; 4083 int i, dev_num, error;
4003 char *stp; 4084 char *stp;
4004 4085
4005 if (SDp->type != TYPE_TAPE) 4086 if (SDp->type != TYPE_TAPE)
@@ -4125,36 +4206,10 @@ static int st_probe(struct device *dev)
4125 4206
4126 dev_set_drvdata(dev, tpnt); 4207 dev_set_drvdata(dev, tpnt);
4127 4208
4128 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4129 STm = &(tpnt->modes[mode]);
4130 for (j=0; j < 2; j++) {
4131 cdev = cdev_alloc();
4132 if (!cdev) {
4133 printk(KERN_ERR
4134 "st%d: out of memory. Device not attached.\n",
4135 dev_num);
4136 cdev_del(cdev);
4137 goto out_free_tape;
4138 }
4139 cdev->owner = THIS_MODULE;
4140 cdev->ops = &st_fops;
4141
4142 error = cdev_add(cdev,
4143 MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, j)),
4144 1);
4145 if (error) {
4146 printk(KERN_ERR "st%d: Can't add %s-rewind mode %d\n",
4147 dev_num, j ? "non" : "auto", mode);
4148 printk(KERN_ERR "st%d: Device not attached.\n", dev_num);
4149 goto out_free_tape;
4150 }
4151 STm->cdevs[j] = cdev;
4152 4209
4153 } 4210 error = create_cdevs(tpnt);
4154 error = do_create_class_files(tpnt, dev_num, mode); 4211 if (error)
4155 if (error) 4212 goto out_remove_devs;
4156 goto out_free_tape;
4157 }
4158 scsi_autopm_put_device(SDp); 4213 scsi_autopm_put_device(SDp);
4159 4214
4160 sdev_printk(KERN_NOTICE, SDp, 4215 sdev_printk(KERN_NOTICE, SDp,
@@ -4165,20 +4220,8 @@ static int st_probe(struct device *dev)
4165 4220
4166 return 0; 4221 return 0;
4167 4222
4168out_free_tape: 4223out_remove_devs:
4169 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj, 4224 remove_cdevs(tpnt);
4170 "tape");
4171 for (mode=0; mode < ST_NBR_MODES; mode++) {
4172 STm = &(tpnt->modes[mode]);
4173 for (j=0; j < 2; j++) {
4174 if (STm->cdevs[j]) {
4175 device_destroy(&st_sysfs_class,
4176 MKDEV(SCSI_TAPE_MAJOR,
4177 TAPE_MINOR(i, mode, j)));
4178 cdev_del(STm->cdevs[j]);
4179 }
4180 }
4181 }
4182out_put_index: 4225out_put_index:
4183 spin_lock(&st_index_lock); 4226 spin_lock(&st_index_lock);
4184 idr_remove(&st_index_idr, dev_num); 4227 idr_remove(&st_index_idr, dev_num);
@@ -4196,24 +4239,10 @@ out:
4196static int st_remove(struct device *dev) 4239static int st_remove(struct device *dev)
4197{ 4240{
4198 struct scsi_tape *tpnt = dev_get_drvdata(dev); 4241 struct scsi_tape *tpnt = dev_get_drvdata(dev);
4199 int rew, mode;
4200 dev_t cdev_devno;
4201 struct cdev *cdev;
4202 int index = tpnt->index; 4242 int index = tpnt->index;
4203 4243
4204 scsi_autopm_get_device(to_scsi_device(dev)); 4244 scsi_autopm_get_device(to_scsi_device(dev));
4205 sysfs_remove_link(&tpnt->device->sdev_gendev.kobj, "tape"); 4245 remove_cdevs(tpnt);
4206 for (mode = 0; mode < ST_NBR_MODES; ++mode) {
4207 for (rew = 0; rew < 2; rew++) {
4208 cdev = tpnt->modes[mode].cdevs[rew];
4209 if (!cdev)
4210 continue;
4211 cdev_devno = cdev->dev;
4212 device_destroy(&st_sysfs_class, cdev_devno);
4213 cdev_del(tpnt->modes[mode].cdevs[rew]);
4214 tpnt->modes[mode].cdevs[rew] = NULL;
4215 }
4216 }
4217 4246
4218 mutex_lock(&st_ref_mutex); 4247 mutex_lock(&st_ref_mutex);
4219 kref_put(&tpnt->kref, scsi_tape_release); 4248 kref_put(&tpnt->kref, scsi_tape_release);
@@ -4462,50 +4491,6 @@ static struct device_attribute st_dev_attrs[] = {
4462 __ATTR_NULL, 4491 __ATTR_NULL,
4463}; 4492};
4464 4493
4465static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
4466{
4467 int i, rew, error;
4468 char name[10];
4469 struct device *st_class_member;
4470
4471 for (rew=0; rew < 2; rew++) {
4472 /* Make sure that the minor numbers corresponding to the four
4473 first modes always get the same names */
4474 i = mode << (4 - ST_NBR_MODE_BITS);
4475 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4476 STp->disk->disk_name, st_formats[i]);
4477 st_class_member =
4478 device_create(&st_sysfs_class,
4479 &STp->device->sdev_gendev,
4480 MKDEV(SCSI_TAPE_MAJOR,
4481 TAPE_MINOR(dev_num, mode, rew)),
4482 &STp->modes[mode], "%s", name);
4483 if (IS_ERR(st_class_member)) {
4484 printk(KERN_WARNING "st%d: device_create failed\n",
4485 dev_num);
4486 error = PTR_ERR(st_class_member);
4487 goto out;
4488 }
4489
4490 if (mode == 0 && rew == 0) {
4491 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4492 &st_class_member->kobj,
4493 "tape");
4494 if (error) {
4495 printk(KERN_ERR
4496 "st%d: Can't create sysfs link from SCSI device.\n",
4497 dev_num);
4498 goto out;
4499 }
4500 }
4501 }
4502
4503 return 0;
4504
4505out:
4506 return error;
4507}
4508
4509/* The following functions may be useful for a larger audience. */ 4494/* The following functions may be useful for a larger audience. */
4510static int sgl_map_user_pages(struct st_buffer *STbp, 4495static int sgl_map_user_pages(struct st_buffer *STbp,
4511 const unsigned int max_pages, unsigned long uaddr, 4496 const unsigned int max_pages, unsigned long uaddr,
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 8a23640981c8..b7a07c7bf4f8 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -67,6 +67,7 @@ struct st_modedef {
67 short default_density; /* Forced density, -1 = no value */ 67 short default_density; /* Forced density, -1 = no value */
68 int default_blksize; /* Forced blocksize, -1 = no value */ 68 int default_blksize; /* Forced blocksize, -1 = no value */
69 struct scsi_tape *tape; 69 struct scsi_tape *tape;
70 struct device *devs[2]; /* Auto-rewind and non-rewind devices */
70 struct cdev *cdevs[2]; /* Auto-rewind and non-rewind devices */ 71 struct cdev *cdevs[2]; /* Auto-rewind and non-rewind devices */
71}; 72};
72 73