aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/osst.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-10-04 05:23:04 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-04 14:12:44 -0400
commit37e0333c68ca9cbddfc0108e1889556287563df0 (patch)
tree2f6b27aff5b6d8e737c9a8f8bccdd8d3a3c25b9a /drivers/scsi/osst.c
parentde77aaff5f0178f44867f131deb5e2cb1610fe6b (diff)
[SCSI] SCSI osst: add error handling to module init, sysfs
- check all sysfs-related return codes, and propagate them back to callers - properly unwind errors in osst_probe(), init_osst(). This fixes a leak that occured if scsi driver registration failed, and fixes an oops if sysfs creation returned an error. (unrelated) - kzalloc() cleanup in new_tape_buf() Signed-off-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/osst.c')
-rw-r--r--drivers/scsi/osst.c131
1 files changed, 91 insertions, 40 deletions
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 9ecb323ebae8..824fe080d1dc 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5206,12 +5206,12 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d
5206 priority = GFP_KERNEL; 5206 priority = GFP_KERNEL;
5207 5207
5208 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); 5208 i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist);
5209 tb = (struct osst_buffer *)kmalloc(i, priority); 5209 tb = kzalloc(i, priority);
5210 if (!tb) { 5210 if (!tb) {
5211 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); 5211 printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n");
5212 return NULL; 5212 return NULL;
5213 } 5213 }
5214 memset(tb, 0, i); 5214
5215 tb->sg_segs = tb->orig_sg_segs = 0; 5215 tb->sg_segs = tb->orig_sg_segs = 0;
5216 tb->use_sg = max_sg; 5216 tb->use_sg = max_sg;
5217 tb->in_use = 1; 5217 tb->in_use = 1;
@@ -5574,9 +5574,9 @@ static ssize_t osst_version_show(struct device_driver *ddd, char *buf)
5574 5574
5575static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); 5575static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL);
5576 5576
5577static void osst_create_driverfs_files(struct device_driver *driverfs) 5577static int osst_create_driverfs_files(struct device_driver *driverfs)
5578{ 5578{
5579 driver_create_file(driverfs, &driver_attr_version); 5579 return driver_create_file(driverfs, &driver_attr_version);
5580} 5580}
5581 5581
5582static void osst_remove_driverfs_files(struct device_driver *driverfs) 5582static void osst_remove_driverfs_files(struct device_driver *driverfs)
@@ -5662,50 +5662,70 @@ CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
5662 5662
5663static struct class *osst_sysfs_class; 5663static struct class *osst_sysfs_class;
5664 5664
5665static int osst_sysfs_valid = 0; 5665static int osst_sysfs_init(void)
5666
5667static void osst_sysfs_init(void)
5668{ 5666{
5669 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); 5667 osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
5670 if ( IS_ERR(osst_sysfs_class) ) 5668 if (IS_ERR(osst_sysfs_class)) {
5671 printk(KERN_WARNING "osst :W: Unable to register sysfs class\n"); 5669 printk(KERN_ERR "osst :W: Unable to register sysfs class\n");
5672 else 5670 return PTR_ERR(osst_sysfs_class);
5673 osst_sysfs_valid = 1; 5671 }
5672
5673 return 0;
5674} 5674}
5675 5675
5676static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) 5676static void osst_sysfs_destroy(dev_t dev)
5677{ 5677{
5678 struct class_device *osst_class_member; 5678 class_device_destroy(osst_sysfs_class, dev);
5679}
5679 5680
5680 if (!osst_sysfs_valid) return; 5681static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name)
5682{
5683 struct class_device *osst_class_member;
5684 int err;
5681 5685
5682 osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name); 5686 osst_class_member = class_device_create(osst_sysfs_class, NULL, dev,
5687 device, "%s", name);
5683 if (IS_ERR(osst_class_member)) { 5688 if (IS_ERR(osst_class_member)) {
5684 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); 5689 printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
5685 return; 5690 return PTR_ERR(osst_class_member);
5686 } 5691 }
5692
5687 class_set_devdata(osst_class_member, STp); 5693 class_set_devdata(osst_class_member, STp);
5688 class_device_create_file(osst_class_member, &class_device_attr_ADR_rev); 5694 err = class_device_create_file(osst_class_member,
5689 class_device_create_file(osst_class_member, &class_device_attr_media_version); 5695 &class_device_attr_ADR_rev);
5690 class_device_create_file(osst_class_member, &class_device_attr_capacity); 5696 if (err)
5691 class_device_create_file(osst_class_member, &class_device_attr_BOT_frame); 5697 goto err_out;
5692 class_device_create_file(osst_class_member, &class_device_attr_EOD_frame); 5698 err = class_device_create_file(osst_class_member,
5693 class_device_create_file(osst_class_member, &class_device_attr_file_count); 5699 &class_device_attr_media_version);
5694} 5700 if (err)
5701 goto err_out;
5702 err = class_device_create_file(osst_class_member,
5703 &class_device_attr_capacity);
5704 if (err)
5705 goto err_out;
5706 err = class_device_create_file(osst_class_member,
5707 &class_device_attr_BOT_frame);
5708 if (err)
5709 goto err_out;
5710 err = class_device_create_file(osst_class_member,
5711 &class_device_attr_EOD_frame);
5712 if (err)
5713 goto err_out;
5714 err = class_device_create_file(osst_class_member,
5715 &class_device_attr_file_count);
5716 if (err)
5717 goto err_out;
5695 5718
5696static void osst_sysfs_destroy(dev_t dev) 5719 return 0;
5697{
5698 if (!osst_sysfs_valid) return;
5699 5720
5700 class_device_destroy(osst_sysfs_class, dev); 5721err_out:
5722 osst_sysfs_destroy(dev);
5723 return err;
5701} 5724}
5702 5725
5703static void osst_sysfs_cleanup(void) 5726static void osst_sysfs_cleanup(void)
5704{ 5727{
5705 if (osst_sysfs_valid) { 5728 class_destroy(osst_sysfs_class);
5706 class_destroy(osst_sysfs_class);
5707 osst_sysfs_valid = 0;
5708 }
5709} 5729}
5710 5730
5711/* 5731/*
@@ -5720,7 +5740,7 @@ static int osst_probe(struct device *dev)
5720 struct st_partstat * STps; 5740 struct st_partstat * STps;
5721 struct osst_buffer * buffer; 5741 struct osst_buffer * buffer;
5722 struct gendisk * drive; 5742 struct gendisk * drive;
5723 int i, dev_num; 5743 int i, dev_num, err = -ENODEV;
5724 5744
5725 if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) 5745 if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
5726 return -ENODEV; 5746 return -ENODEV;
@@ -5848,13 +5868,20 @@ static int osst_probe(struct device *dev)
5848 init_MUTEX(&tpnt->lock); 5868 init_MUTEX(&tpnt->lock);
5849 osst_nr_dev++; 5869 osst_nr_dev++;
5850 write_unlock(&os_scsi_tapes_lock); 5870 write_unlock(&os_scsi_tapes_lock);
5871
5851 { 5872 {
5852 char name[8]; 5873 char name[8];
5874
5853 /* Rewind entry */ 5875 /* Rewind entry */
5854 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); 5876 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt));
5877 if (err)
5878 goto out_free_buffer;
5879
5855 /* No-rewind entry */ 5880 /* No-rewind entry */
5856 snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); 5881 snprintf(name, 8, "%s%s", "n", tape_name(tpnt));
5857 osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); 5882 err = osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name);
5883 if (err)
5884 goto out_free_sysfs1;
5858 } 5885 }
5859 5886
5860 sdev_printk(KERN_INFO, SDp, 5887 sdev_printk(KERN_INFO, SDp,
@@ -5863,9 +5890,13 @@ static int osst_probe(struct device *dev)
5863 5890
5864 return 0; 5891 return 0;
5865 5892
5893out_free_sysfs1:
5894 osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num));
5895out_free_buffer:
5896 kfree(buffer);
5866out_put_disk: 5897out_put_disk:
5867 put_disk(drive); 5898 put_disk(drive);
5868 return -ENODEV; 5899 return err;
5869}; 5900};
5870 5901
5871static int osst_remove(struct device *dev) 5902static int osst_remove(struct device *dev)
@@ -5902,19 +5933,39 @@ static int osst_remove(struct device *dev)
5902 5933
5903static int __init init_osst(void) 5934static int __init init_osst(void)
5904{ 5935{
5936 int err;
5937
5905 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); 5938 printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid);
5906 5939
5907 validate_options(); 5940 validate_options();
5908 osst_sysfs_init();
5909 5941
5910 if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) { 5942 err = osst_sysfs_init();
5943 if (err)
5944 return err;
5945
5946 err = register_chrdev(OSST_MAJOR, "osst", &osst_fops);
5947 if (err < 0) {
5911 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); 5948 printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
5912 osst_sysfs_cleanup(); 5949 goto err_out;
5913 return 1;
5914 } 5950 }
5915 osst_create_driverfs_files(&osst_template.gendrv); 5951
5952 err = scsi_register_driver(&osst_template.gendrv);
5953 if (err)
5954 goto err_out_chrdev;
5955
5956 err = osst_create_driverfs_files(&osst_template.gendrv);
5957 if (err)
5958 goto err_out_scsidrv;
5916 5959
5917 return 0; 5960 return 0;
5961
5962err_out_scsidrv:
5963 scsi_unregister_driver(&osst_template.gendrv);
5964err_out_chrdev:
5965 unregister_chrdev(OSST_MAJOR, "osst");
5966err_out:
5967 osst_sysfs_cleanup();
5968 return err;
5918} 5969}
5919 5970
5920static void __exit exit_osst (void) 5971static void __exit exit_osst (void)