aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-10-04 06:00:38 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-04 14:16:29 -0400
commit13026a6b985b9d1e19330d5656e211f15b5aca3b (patch)
tree615cd268538ced98adc5cc26b15daeea65b7221f
parent5e4009ba3d5af40f5615fdb4304cc4a9947cca0a (diff)
[SCSI] SCSI st: fix error handling in module init, sysfs
- Notice and handle sysfs errors in module init, tape init - Properly unwind errors in module init - Remove bogus st_sysfs_class==NULL test, it is guaranteed !NULL at that point Signed-off-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/st.c115
1 files changed, 78 insertions, 37 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 7f669b600677..3babdc76b3fb 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -195,9 +195,9 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
195static int st_probe(struct device *); 195static int st_probe(struct device *);
196static int st_remove(struct device *); 196static int st_remove(struct device *);
197 197
198static void do_create_driverfs_files(void); 198static int do_create_driverfs_files(void);
199static void do_remove_driverfs_files(void); 199static void do_remove_driverfs_files(void);
200static void do_create_class_files(struct scsi_tape *, int, int); 200static int do_create_class_files(struct scsi_tape *, int, int);
201 201
202static struct scsi_driver st_template = { 202static struct scsi_driver st_template = {
203 .owner = THIS_MODULE, 203 .owner = THIS_MODULE,
@@ -4048,7 +4048,9 @@ static int st_probe(struct device *dev)
4048 STm->cdevs[j] = cdev; 4048 STm->cdevs[j] = cdev;
4049 4049
4050 } 4050 }
4051 do_create_class_files(tpnt, dev_num, mode); 4051 error = do_create_class_files(tpnt, dev_num, mode);
4052 if (error)
4053 goto out_free_tape;
4052 } 4054 }
4053 4055
4054 sdev_printk(KERN_WARNING, SDp, 4056 sdev_printk(KERN_WARNING, SDp,
@@ -4157,32 +4159,45 @@ static void scsi_tape_release(struct kref *kref)
4157 4159
4158static int __init init_st(void) 4160static int __init init_st(void)
4159{ 4161{
4162 int err;
4163
4160 validate_options(); 4164 validate_options();
4161 4165
4162 printk(KERN_INFO 4166 printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
4163 "st: Version %s, fixed bufsize %d, s/g segs %d\n",
4164 verstr, st_fixed_buffer_size, st_max_sg_segs); 4167 verstr, st_fixed_buffer_size, st_max_sg_segs);
4165 4168
4166 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape"); 4169 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
4167 if (IS_ERR(st_sysfs_class)) { 4170 if (IS_ERR(st_sysfs_class)) {
4168 st_sysfs_class = NULL;
4169 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n"); 4171 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
4170 return 1; 4172 return PTR_ERR(st_sysfs_class);
4171 } 4173 }
4172 4174
4173 if (!register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), 4175 err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4174 ST_MAX_TAPE_ENTRIES, "st")) { 4176 ST_MAX_TAPE_ENTRIES, "st");
4175 if (scsi_register_driver(&st_template.gendrv) == 0) { 4177 if (err) {
4176 do_create_driverfs_files(); 4178 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
4177 return 0; 4179 SCSI_TAPE_MAJOR);
4178 } 4180 goto err_class;
4179 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4180 ST_MAX_TAPE_ENTRIES);
4181 } 4181 }
4182 class_destroy(st_sysfs_class);
4183 4182
4184 printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR); 4183 err = scsi_register_driver(&st_template.gendrv);
4185 return 1; 4184 if (err)
4185 goto err_chrdev;
4186
4187 err = do_create_driverfs_files();
4188 if (err)
4189 goto err_scsidrv;
4190
4191 return 0;
4192
4193err_scsidrv:
4194 scsi_unregister_driver(&st_template.gendrv);
4195err_chrdev:
4196 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4197 ST_MAX_TAPE_ENTRIES);
4198err_class:
4199 class_destroy(st_sysfs_class);
4200 return err;
4186} 4201}
4187 4202
4188static void __exit exit_st(void) 4203static void __exit exit_st(void)
@@ -4225,14 +4240,33 @@ static ssize_t st_version_show(struct device_driver *ddd, char *buf)
4225} 4240}
4226static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL); 4241static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
4227 4242
4228static void do_create_driverfs_files(void) 4243static int do_create_driverfs_files(void)
4229{ 4244{
4230 struct device_driver *driverfs = &st_template.gendrv; 4245 struct device_driver *driverfs = &st_template.gendrv;
4246 int err;
4247
4248 err = driver_create_file(driverfs, &driver_attr_try_direct_io);
4249 if (err)
4250 return err;
4251 err = driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
4252 if (err)
4253 goto err_try_direct_io;
4254 err = driver_create_file(driverfs, &driver_attr_max_sg_segs);
4255 if (err)
4256 goto err_attr_fixed_buf;
4257 err = driver_create_file(driverfs, &driver_attr_version);
4258 if (err)
4259 goto err_attr_max_sg;
4231 4260
4232 driver_create_file(driverfs, &driver_attr_try_direct_io); 4261 return 0;
4233 driver_create_file(driverfs, &driver_attr_fixed_buffer_size); 4262
4234 driver_create_file(driverfs, &driver_attr_max_sg_segs); 4263err_attr_max_sg:
4235 driver_create_file(driverfs, &driver_attr_version); 4264 driver_remove_file(driverfs, &driver_attr_max_sg_segs);
4265err_attr_fixed_buf:
4266 driver_remove_file(driverfs, &driver_attr_fixed_buffer_size);
4267err_try_direct_io:
4268 driver_remove_file(driverfs, &driver_attr_try_direct_io);
4269 return err;
4236} 4270}
4237 4271
4238static void do_remove_driverfs_files(void) 4272static void do_remove_driverfs_files(void)
@@ -4293,15 +4327,12 @@ static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf)
4293 4327
4294CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL); 4328CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
4295 4329
4296static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) 4330static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
4297{ 4331{
4298 int i, rew, error; 4332 int i, rew, error;
4299 char name[10]; 4333 char name[10];
4300 struct class_device *st_class_member; 4334 struct class_device *st_class_member;
4301 4335
4302 if (!st_sysfs_class)
4303 return;
4304
4305 for (rew=0; rew < 2; rew++) { 4336 for (rew=0; rew < 2; rew++) {
4306 /* Make sure that the minor numbers corresponding to the four 4337 /* Make sure that the minor numbers corresponding to the four
4307 first modes always get the same names */ 4338 first modes always get the same names */
@@ -4316,18 +4347,24 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
4316 if (IS_ERR(st_class_member)) { 4347 if (IS_ERR(st_class_member)) {
4317 printk(KERN_WARNING "st%d: class_device_create failed\n", 4348 printk(KERN_WARNING "st%d: class_device_create failed\n",
4318 dev_num); 4349 dev_num);
4350 error = PTR_ERR(st_class_member);
4319 goto out; 4351 goto out;
4320 } 4352 }
4321 class_set_devdata(st_class_member, &STp->modes[mode]); 4353 class_set_devdata(st_class_member, &STp->modes[mode]);
4322 4354
4323 class_device_create_file(st_class_member, 4355 error = class_device_create_file(st_class_member,
4324 &class_device_attr_defined); 4356 &class_device_attr_defined);
4325 class_device_create_file(st_class_member, 4357 if (error) goto out;
4326 &class_device_attr_default_blksize); 4358 error = class_device_create_file(st_class_member,
4327 class_device_create_file(st_class_member, 4359 &class_device_attr_default_blksize);
4328 &class_device_attr_default_density); 4360 if (error) goto out;
4329 class_device_create_file(st_class_member, 4361 error = class_device_create_file(st_class_member,
4330 &class_device_attr_default_compression); 4362 &class_device_attr_default_density);
4363 if (error) goto out;
4364 error = class_device_create_file(st_class_member,
4365 &class_device_attr_default_compression);
4366 if (error) goto out;
4367
4331 if (mode == 0 && rew == 0) { 4368 if (mode == 0 && rew == 0) {
4332 error = sysfs_create_link(&STp->device->sdev_gendev.kobj, 4369 error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
4333 &st_class_member->kobj, 4370 &st_class_member->kobj,
@@ -4336,11 +4373,15 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
4336 printk(KERN_ERR 4373 printk(KERN_ERR
4337 "st%d: Can't create sysfs link from SCSI device.\n", 4374 "st%d: Can't create sysfs link from SCSI device.\n",
4338 dev_num); 4375 dev_num);
4376 goto out;
4339 } 4377 }
4340 } 4378 }
4341 } 4379 }
4342 out: 4380
4343 return; 4381 return 0;
4382
4383out:
4384 return error;
4344} 4385}
4345 4386
4346/* The following functions may be useful for a larger audience. */ 4387/* The following functions may be useful for a larger audience. */