diff options
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r-- | drivers/scsi/st.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 24211d0efa6d..5b7388f1c835 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -9,7 +9,7 @@ Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, Michael Schaefer, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2008 Kai Makisara + Copyright 1992 - 2010 Kai Makisara email Kai.Makisara@kolumbus.fi Some small formal changes - aeb, 950809 @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support */ -static const char *verstr = "20081215"; +static const char *verstr = "20100829"; #include <linux/module.h> @@ -39,7 +39,6 @@ static const char *verstr = "20081215"; #include <linux/cdev.h> #include <linux/delay.h> #include <linux/mutex.h> -#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/dma.h> @@ -76,6 +75,7 @@ static const char *verstr = "20081215"; #include "st_options.h" #include "st.h" +static DEFINE_MUTEX(st_mutex); static int buffer_kbs; static int max_sg_segs; static int try_direct_io = TRY_DIRECT_IO; @@ -1180,7 +1180,7 @@ static int st_open(struct inode *inode, struct file *filp) int dev = TAPE_NR(inode); char *name; - lock_kernel(); + mutex_lock(&st_mutex); /* * We really want to do nonseekable_open(inode, filp); here, but some * versions of tar incorrectly call lseek on tapes and bail out if that @@ -1189,7 +1189,7 @@ static int st_open(struct inode *inode, struct file *filp) filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); if (!(STp = scsi_tape_get(dev))) { - unlock_kernel(); + mutex_unlock(&st_mutex); return -ENXIO; } @@ -1200,7 +1200,7 @@ static int st_open(struct inode *inode, struct file *filp) if (STp->in_use) { write_unlock(&st_dev_arr_lock); scsi_tape_put(STp); - unlock_kernel(); + mutex_unlock(&st_mutex); DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); ) return (-EBUSY); } @@ -1249,14 +1249,14 @@ static int st_open(struct inode *inode, struct file *filp) retval = (-EIO); goto err_out; } - unlock_kernel(); + mutex_unlock(&st_mutex); return 0; err_out: normalize_buffer(STp->buffer); STp->in_use = 0; scsi_tape_put(STp); - unlock_kernel(); + mutex_unlock(&st_mutex); return retval; } @@ -2696,18 +2696,21 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon } break; case MTWEOF: + case MTWEOFI: case MTWSM: if (STp->write_prot) return (-EACCES); cmd[0] = WRITE_FILEMARKS; if (cmd_in == MTWSM) cmd[1] = 2; + if (cmd_in == MTWEOFI) + cmd[1] |= 1; cmd[2] = (arg >> 16); cmd[3] = (arg >> 8); cmd[4] = arg; timeout = STp->device->request_queue->rq_timeout; DEBC( - if (cmd_in == MTWEOF) + if (cmd_in != MTWSM) printk(ST_DEB_MSG "%s: Writing %d filemarks.\n", name, cmd[2] * 65536 + cmd[3] * 256 + cmd[4]); else @@ -2883,8 +2886,8 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon else if (chg_eof) STps->eof = ST_NOEOF; - if (cmd_in == MTWEOF) - STps->rw = ST_IDLE; + if (cmd_in == MTWEOF || cmd_in == MTWEOFI) + STps->rw = ST_IDLE; /* prevent automatic WEOF at close */ } else { /* SCSI command was not completely successful. Don't return from this block without releasing the SCSI command block! */ struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat; @@ -2901,7 +2904,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon else undone = 0; - if (cmd_in == MTWEOF && + if ((cmd_in == MTWEOF || cmd_in == MTWEOFI) && cmdstatp->have_sense && (cmdstatp->flags & SENSE_EOM)) { if (cmdstatp->sense_hdr.sense_key == NO_SENSE || |