diff options
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r-- | drivers/scsi/st.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 6e5a5bb31311..4684cc716aa4 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -38,6 +38,7 @@ static const char *verstr = "20080224"; | |||
38 | #include <linux/cdev.h> | 38 | #include <linux/cdev.h> |
39 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
40 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
41 | #include <linux/smp_lock.h> | ||
41 | 42 | ||
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
43 | #include <asm/dma.h> | 44 | #include <asm/dma.h> |
@@ -1113,7 +1114,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) | |||
1113 | } | 1114 | } |
1114 | 1115 | ||
1115 | 1116 | ||
1116 | /* Open the device. Needs to be called with BKL only because of incrementing the SCSI host | 1117 | /* Open the device. Needs to take the BKL only because of incrementing the SCSI host |
1117 | module count. */ | 1118 | module count. */ |
1118 | static int st_open(struct inode *inode, struct file *filp) | 1119 | static int st_open(struct inode *inode, struct file *filp) |
1119 | { | 1120 | { |
@@ -1123,6 +1124,7 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1123 | int dev = TAPE_NR(inode); | 1124 | int dev = TAPE_NR(inode); |
1124 | char *name; | 1125 | char *name; |
1125 | 1126 | ||
1127 | lock_kernel(); | ||
1126 | /* | 1128 | /* |
1127 | * We really want to do nonseekable_open(inode, filp); here, but some | 1129 | * We really want to do nonseekable_open(inode, filp); here, but some |
1128 | * versions of tar incorrectly call lseek on tapes and bail out if that | 1130 | * versions of tar incorrectly call lseek on tapes and bail out if that |
@@ -1130,8 +1132,10 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1130 | */ | 1132 | */ |
1131 | filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); | 1133 | filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); |
1132 | 1134 | ||
1133 | if (!(STp = scsi_tape_get(dev))) | 1135 | if (!(STp = scsi_tape_get(dev))) { |
1136 | unlock_kernel(); | ||
1134 | return -ENXIO; | 1137 | return -ENXIO; |
1138 | } | ||
1135 | 1139 | ||
1136 | write_lock(&st_dev_arr_lock); | 1140 | write_lock(&st_dev_arr_lock); |
1137 | filp->private_data = STp; | 1141 | filp->private_data = STp; |
@@ -1140,6 +1144,7 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1140 | if (STp->in_use) { | 1144 | if (STp->in_use) { |
1141 | write_unlock(&st_dev_arr_lock); | 1145 | write_unlock(&st_dev_arr_lock); |
1142 | scsi_tape_put(STp); | 1146 | scsi_tape_put(STp); |
1147 | unlock_kernel(); | ||
1143 | DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); ) | 1148 | DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); ) |
1144 | return (-EBUSY); | 1149 | return (-EBUSY); |
1145 | } | 1150 | } |
@@ -1188,12 +1193,14 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1188 | retval = (-EIO); | 1193 | retval = (-EIO); |
1189 | goto err_out; | 1194 | goto err_out; |
1190 | } | 1195 | } |
1196 | unlock_kernel(); | ||
1191 | return 0; | 1197 | return 0; |
1192 | 1198 | ||
1193 | err_out: | 1199 | err_out: |
1194 | normalize_buffer(STp->buffer); | 1200 | normalize_buffer(STp->buffer); |
1195 | STp->in_use = 0; | 1201 | STp->in_use = 0; |
1196 | scsi_tape_put(STp); | 1202 | scsi_tape_put(STp); |
1203 | unlock_kernel(); | ||
1197 | return retval; | 1204 | return retval; |
1198 | 1205 | ||
1199 | } | 1206 | } |