diff options
Diffstat (limited to 'drivers/scsi/osst.c')
-rw-r--r-- | drivers/scsi/osst.c | 134 |
1 files changed, 92 insertions, 42 deletions
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 4a2fed350d4e..824fe080d1dc 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c | |||
@@ -4843,8 +4843,7 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp) | |||
4843 | static int osst_ioctl(struct inode * inode,struct file * file, | 4843 | static int osst_ioctl(struct inode * inode,struct file * file, |
4844 | unsigned int cmd_in, unsigned long arg) | 4844 | unsigned int cmd_in, unsigned long arg) |
4845 | { | 4845 | { |
4846 | int i, cmd_nr, cmd_type, retval = 0; | 4846 | int i, cmd_nr, cmd_type, blk, retval = 0; |
4847 | unsigned int blk; | ||
4848 | struct st_modedef * STm; | 4847 | struct st_modedef * STm; |
4849 | struct st_partstat * STps; | 4848 | struct st_partstat * STps; |
4850 | struct osst_request * SRpnt = NULL; | 4849 | struct osst_request * SRpnt = NULL; |
@@ -5207,12 +5206,12 @@ static struct osst_buffer * new_tape_buffer( int from_initialization, int need_d | |||
5207 | priority = GFP_KERNEL; | 5206 | priority = GFP_KERNEL; |
5208 | 5207 | ||
5209 | 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); |
5210 | tb = (struct osst_buffer *)kmalloc(i, priority); | 5209 | tb = kzalloc(i, priority); |
5211 | if (!tb) { | 5210 | if (!tb) { |
5212 | 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"); |
5213 | return NULL; | 5212 | return NULL; |
5214 | } | 5213 | } |
5215 | memset(tb, 0, i); | 5214 | |
5216 | tb->sg_segs = tb->orig_sg_segs = 0; | 5215 | tb->sg_segs = tb->orig_sg_segs = 0; |
5217 | tb->use_sg = max_sg; | 5216 | tb->use_sg = max_sg; |
5218 | tb->in_use = 1; | 5217 | tb->in_use = 1; |
@@ -5575,9 +5574,9 @@ static ssize_t osst_version_show(struct device_driver *ddd, char *buf) | |||
5575 | 5574 | ||
5576 | static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); | 5575 | static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); |
5577 | 5576 | ||
5578 | static void osst_create_driverfs_files(struct device_driver *driverfs) | 5577 | static int osst_create_driverfs_files(struct device_driver *driverfs) |
5579 | { | 5578 | { |
5580 | driver_create_file(driverfs, &driver_attr_version); | 5579 | return driver_create_file(driverfs, &driver_attr_version); |
5581 | } | 5580 | } |
5582 | 5581 | ||
5583 | static void osst_remove_driverfs_files(struct device_driver *driverfs) | 5582 | static void osst_remove_driverfs_files(struct device_driver *driverfs) |
@@ -5663,50 +5662,70 @@ CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL); | |||
5663 | 5662 | ||
5664 | static struct class *osst_sysfs_class; | 5663 | static struct class *osst_sysfs_class; |
5665 | 5664 | ||
5666 | static int osst_sysfs_valid = 0; | 5665 | static int osst_sysfs_init(void) |
5667 | |||
5668 | static void osst_sysfs_init(void) | ||
5669 | { | 5666 | { |
5670 | osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); | 5667 | osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape"); |
5671 | if ( IS_ERR(osst_sysfs_class) ) | 5668 | if (IS_ERR(osst_sysfs_class)) { |
5672 | printk(KERN_WARNING "osst :W: Unable to register sysfs class\n"); | 5669 | printk(KERN_ERR "osst :W: Unable to register sysfs class\n"); |
5673 | else | 5670 | return PTR_ERR(osst_sysfs_class); |
5674 | osst_sysfs_valid = 1; | 5671 | } |
5672 | |||
5673 | return 0; | ||
5675 | } | 5674 | } |
5676 | 5675 | ||
5677 | static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) | 5676 | static void osst_sysfs_destroy(dev_t dev) |
5678 | { | 5677 | { |
5679 | struct class_device *osst_class_member; | 5678 | class_device_destroy(osst_sysfs_class, dev); |
5679 | } | ||
5680 | 5680 | ||
5681 | if (!osst_sysfs_valid) return; | 5681 | static 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; | ||
5682 | 5685 | ||
5683 | 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); | ||
5684 | if (IS_ERR(osst_class_member)) { | 5688 | if (IS_ERR(osst_class_member)) { |
5685 | 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); |
5686 | return; | 5690 | return PTR_ERR(osst_class_member); |
5687 | } | 5691 | } |
5692 | |||
5688 | class_set_devdata(osst_class_member, STp); | 5693 | class_set_devdata(osst_class_member, STp); |
5689 | class_device_create_file(osst_class_member, &class_device_attr_ADR_rev); | 5694 | err = class_device_create_file(osst_class_member, |
5690 | class_device_create_file(osst_class_member, &class_device_attr_media_version); | 5695 | &class_device_attr_ADR_rev); |
5691 | class_device_create_file(osst_class_member, &class_device_attr_capacity); | 5696 | if (err) |
5692 | class_device_create_file(osst_class_member, &class_device_attr_BOT_frame); | 5697 | goto err_out; |
5693 | class_device_create_file(osst_class_member, &class_device_attr_EOD_frame); | 5698 | err = class_device_create_file(osst_class_member, |
5694 | class_device_create_file(osst_class_member, &class_device_attr_file_count); | 5699 | &class_device_attr_media_version); |
5695 | } | 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; | ||
5696 | 5718 | ||
5697 | static void osst_sysfs_destroy(dev_t dev) | 5719 | return 0; |
5698 | { | ||
5699 | if (!osst_sysfs_valid) return; | ||
5700 | 5720 | ||
5701 | class_device_destroy(osst_sysfs_class, dev); | 5721 | err_out: |
5722 | osst_sysfs_destroy(dev); | ||
5723 | return err; | ||
5702 | } | 5724 | } |
5703 | 5725 | ||
5704 | static void osst_sysfs_cleanup(void) | 5726 | static void osst_sysfs_cleanup(void) |
5705 | { | 5727 | { |
5706 | if (osst_sysfs_valid) { | 5728 | class_destroy(osst_sysfs_class); |
5707 | class_destroy(osst_sysfs_class); | ||
5708 | osst_sysfs_valid = 0; | ||
5709 | } | ||
5710 | } | 5729 | } |
5711 | 5730 | ||
5712 | /* | 5731 | /* |
@@ -5721,7 +5740,7 @@ static int osst_probe(struct device *dev) | |||
5721 | struct st_partstat * STps; | 5740 | struct st_partstat * STps; |
5722 | struct osst_buffer * buffer; | 5741 | struct osst_buffer * buffer; |
5723 | struct gendisk * drive; | 5742 | struct gendisk * drive; |
5724 | int i, dev_num; | 5743 | int i, dev_num, err = -ENODEV; |
5725 | 5744 | ||
5726 | if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) | 5745 | if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) |
5727 | return -ENODEV; | 5746 | return -ENODEV; |
@@ -5849,13 +5868,20 @@ static int osst_probe(struct device *dev) | |||
5849 | init_MUTEX(&tpnt->lock); | 5868 | init_MUTEX(&tpnt->lock); |
5850 | osst_nr_dev++; | 5869 | osst_nr_dev++; |
5851 | write_unlock(&os_scsi_tapes_lock); | 5870 | write_unlock(&os_scsi_tapes_lock); |
5871 | |||
5852 | { | 5872 | { |
5853 | char name[8]; | 5873 | char name[8]; |
5874 | |||
5854 | /* Rewind entry */ | 5875 | /* Rewind entry */ |
5855 | 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 | |||
5856 | /* No-rewind entry */ | 5880 | /* No-rewind entry */ |
5857 | snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); | 5881 | snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); |
5858 | 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; | ||
5859 | } | 5885 | } |
5860 | 5886 | ||
5861 | sdev_printk(KERN_INFO, SDp, | 5887 | sdev_printk(KERN_INFO, SDp, |
@@ -5864,9 +5890,13 @@ static int osst_probe(struct device *dev) | |||
5864 | 5890 | ||
5865 | return 0; | 5891 | return 0; |
5866 | 5892 | ||
5893 | out_free_sysfs1: | ||
5894 | osst_sysfs_destroy(MKDEV(OSST_MAJOR, dev_num)); | ||
5895 | out_free_buffer: | ||
5896 | kfree(buffer); | ||
5867 | out_put_disk: | 5897 | out_put_disk: |
5868 | put_disk(drive); | 5898 | put_disk(drive); |
5869 | return -ENODEV; | 5899 | return err; |
5870 | }; | 5900 | }; |
5871 | 5901 | ||
5872 | static int osst_remove(struct device *dev) | 5902 | static int osst_remove(struct device *dev) |
@@ -5903,19 +5933,39 @@ static int osst_remove(struct device *dev) | |||
5903 | 5933 | ||
5904 | static int __init init_osst(void) | 5934 | static int __init init_osst(void) |
5905 | { | 5935 | { |
5936 | int err; | ||
5937 | |||
5906 | 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); |
5907 | 5939 | ||
5908 | validate_options(); | 5940 | validate_options(); |
5909 | osst_sysfs_init(); | ||
5910 | 5941 | ||
5911 | 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) { | ||
5912 | 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); |
5913 | osst_sysfs_cleanup(); | 5949 | goto err_out; |
5914 | return 1; | ||
5915 | } | 5950 | } |
5916 | 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; | ||
5917 | 5959 | ||
5918 | return 0; | 5960 | return 0; |
5961 | |||
5962 | err_out_scsidrv: | ||
5963 | scsi_unregister_driver(&osst_template.gendrv); | ||
5964 | err_out_chrdev: | ||
5965 | unregister_chrdev(OSST_MAJOR, "osst"); | ||
5966 | err_out: | ||
5967 | osst_sysfs_cleanup(); | ||
5968 | return err; | ||
5919 | } | 5969 | } |
5920 | 5970 | ||
5921 | static void __exit exit_osst (void) | 5971 | static void __exit exit_osst (void) |