diff options
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r-- | drivers/scsi/st.c | 47 |
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 | ||
20 | static char *verstr = "20050312"; | 20 | static 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; | |||
82 | static int st_dev_max; | 84 | static int st_dev_max; |
83 | static int st_nr_dev; | 85 | static int st_nr_dev; |
84 | 86 | ||
85 | static struct class_simple *st_sysfs_class; | 87 | static struct class *st_sysfs_class; |
86 | 88 | ||
87 | MODULE_AUTHOR("Kai Makisara"); | 89 | MODULE_AUTHOR("Kai Makisara"); |
88 | MODULE_DESCRIPTION("SCSI Tape Driver"); | 90 | MODULE_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) | |||
4154 | static void __exit exit_st(void) | 4163 | static 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 | } |