aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/st.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r--drivers/scsi/st.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 265d1eed64f..0291a8fb654 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support 17 Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
18 */ 18 */
19 19
20static char *verstr = "20050312"; 20static char *verstr = "20050501";
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23 23
@@ -29,6 +29,7 @@ static char *verstr = "20050312";
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/mtio.h> 31#include <linux/mtio.h>
32#include <linux/cdrom.h>
32#include <linux/ioctl.h> 33#include <linux/ioctl.h>
33#include <linux/fcntl.h> 34#include <linux/fcntl.h>
34#include <linux/spinlock.h> 35#include <linux/spinlock.h>
@@ -50,6 +51,7 @@ static char *verstr = "20050312";
50#include <scsi/scsi_host.h> 51#include <scsi/scsi_host.h>
51#include <scsi/scsi_ioctl.h> 52#include <scsi/scsi_ioctl.h>
52#include <scsi/scsi_request.h> 53#include <scsi/scsi_request.h>
54#include <scsi/sg.h>
53 55
54 56
55/* The driver prints some debugging information on the console if DEBUG 57/* The driver prints some debugging information on the console if DEBUG
@@ -82,7 +84,7 @@ static int try_wdio = 1;
82static int st_dev_max; 84static int st_dev_max;
83static int st_nr_dev; 85static int st_nr_dev;
84 86
85static struct class_simple *st_sysfs_class; 87static struct class *st_sysfs_class;
86 88
87MODULE_AUTHOR("Kai Makisara"); 89MODULE_AUTHOR("Kai Makisara");
88MODULE_DESCRIPTION("SCSI Tape Driver"); 90MODULE_DESCRIPTION("SCSI Tape Driver");
@@ -3463,7 +3465,10 @@ static int st_ioctl(struct inode *inode, struct file *file,
3463 case SCSI_IOCTL_GET_BUS_NUMBER: 3465 case SCSI_IOCTL_GET_BUS_NUMBER:
3464 break; 3466 break;
3465 default: 3467 default:
3466 if (!capable(CAP_SYS_ADMIN)) 3468 if ((cmd_in == SG_IO ||
3469 cmd_in == SCSI_IOCTL_SEND_COMMAND ||
3470 cmd_in == CDROM_SEND_PACKET) &&
3471 !capable(CAP_SYS_RAWIO))
3467 i = -EPERM; 3472 i = -EPERM;
3468 else 3473 else
3469 i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p); 3474 i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p);
@@ -3471,10 +3476,12 @@ static int st_ioctl(struct inode *inode, struct file *file,
3471 return i; 3476 return i;
3472 break; 3477 break;
3473 } 3478 }
3474 if (!capable(CAP_SYS_ADMIN) && 3479 retval = scsi_ioctl(STp->device, cmd_in, p);
3475 (cmd_in == SCSI_IOCTL_START_UNIT || cmd_in == SCSI_IOCTL_STOP_UNIT)) 3480 if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
3476 return -EPERM; 3481 STp->rew_at_close = 0;
3477 return scsi_ioctl(STp->device, cmd_in, p); 3482 STp->ready = ST_NO_TAPE;
3483 }
3484 return retval;
3478 3485
3479 out: 3486 out:
3480 up(&STp->lock); 3487 up(&STp->lock);
@@ -4017,8 +4024,9 @@ out_free_tape:
4017 if (STm->cdevs[j]) { 4024 if (STm->cdevs[j]) {
4018 if (cdev == STm->cdevs[j]) 4025 if (cdev == STm->cdevs[j])
4019 cdev = NULL; 4026 cdev = NULL;
4020 class_simple_device_remove(MKDEV(SCSI_TAPE_MAJOR, 4027 class_device_destroy(st_sysfs_class,
4021 TAPE_MINOR(i, mode, j))); 4028 MKDEV(SCSI_TAPE_MAJOR,
4029 TAPE_MINOR(i, mode, j)));
4022 cdev_del(STm->cdevs[j]); 4030 cdev_del(STm->cdevs[j]);
4023 } 4031 }
4024 } 4032 }
@@ -4061,8 +4069,9 @@ static int st_remove(struct device *dev)
4061 devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]); 4069 devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]);
4062 devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]); 4070 devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]);
4063 for (j=0; j < 2; j++) { 4071 for (j=0; j < 2; j++) {
4064 class_simple_device_remove(MKDEV(SCSI_TAPE_MAJOR, 4072 class_device_destroy(st_sysfs_class,
4065 TAPE_MINOR(i, mode, j))); 4073 MKDEV(SCSI_TAPE_MAJOR,
4074 TAPE_MINOR(i, mode, j)));
4066 cdev_del(tpnt->modes[mode].cdevs[j]); 4075 cdev_del(tpnt->modes[mode].cdevs[j]);
4067 tpnt->modes[mode].cdevs[j] = NULL; 4076 tpnt->modes[mode].cdevs[j] = NULL;
4068 } 4077 }
@@ -4127,7 +4136,7 @@ static int __init init_st(void)
4127 "st: Version %s, fixed bufsize %d, s/g segs %d\n", 4136 "st: Version %s, fixed bufsize %d, s/g segs %d\n",
4128 verstr, st_fixed_buffer_size, st_max_sg_segs); 4137 verstr, st_fixed_buffer_size, st_max_sg_segs);
4129 4138
4130 st_sysfs_class = class_simple_create(THIS_MODULE, "scsi_tape"); 4139 st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
4131 if (IS_ERR(st_sysfs_class)) { 4140 if (IS_ERR(st_sysfs_class)) {
4132 st_sysfs_class = NULL; 4141 st_sysfs_class = NULL;
4133 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n"); 4142 printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
@@ -4141,7 +4150,7 @@ static int __init init_st(void)
4141 return 0; 4150 return 0;
4142 } 4151 }
4143 if (st_sysfs_class) 4152 if (st_sysfs_class)
4144 class_simple_destroy(st_sysfs_class); 4153 class_destroy(st_sysfs_class);
4145 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), 4154 unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
4146 4155
4147 ST_MAX_TAPE_ENTRIES); 4156 ST_MAX_TAPE_ENTRIES);
@@ -4154,7 +4163,7 @@ static int __init init_st(void)
4154static void __exit exit_st(void) 4163static void __exit exit_st(void)
4155{ 4164{
4156 if (st_sysfs_class) 4165 if (st_sysfs_class)
4157 class_simple_destroy(st_sysfs_class); 4166 class_destroy(st_sysfs_class);
4158 st_sysfs_class = NULL; 4167 st_sysfs_class = NULL;
4159 do_remove_driverfs_files(); 4168 do_remove_driverfs_files();
4160 scsi_unregister_driver(&st_template.gendrv); 4169 scsi_unregister_driver(&st_template.gendrv);
@@ -4277,12 +4286,12 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
4277 snprintf(name, 10, "%s%s%s", rew ? "n" : "", 4286 snprintf(name, 10, "%s%s%s", rew ? "n" : "",
4278 STp->disk->disk_name, st_formats[i]); 4287 STp->disk->disk_name, st_formats[i]);
4279 st_class_member = 4288 st_class_member =
4280 class_simple_device_add(st_sysfs_class, 4289 class_device_create(st_sysfs_class,
4281 MKDEV(SCSI_TAPE_MAJOR, 4290 MKDEV(SCSI_TAPE_MAJOR,
4282 TAPE_MINOR(dev_num, mode, rew)), 4291 TAPE_MINOR(dev_num, mode, rew)),
4283 &STp->device->sdev_gendev, "%s", name); 4292 &STp->device->sdev_gendev, "%s", name);
4284 if (IS_ERR(st_class_member)) { 4293 if (IS_ERR(st_class_member)) {
4285 printk(KERN_WARNING "st%d: class_simple_device_add failed\n", 4294 printk(KERN_WARNING "st%d: class_device_create failed\n",
4286 dev_num); 4295 dev_num);
4287 goto out; 4296 goto out;
4288 } 4297 }