]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/st.c
Merge branch 'v28-range-hrtimers-for-linus-v2' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-omap-h63xx.git] / drivers / scsi / st.c
index 6e5a5bb3131150012d24c3a8ac0fab668af289ef..c959bdc55f4f765d7a02c096a6b1be64ca30c0c8 100644 (file)
@@ -17,7 +17,7 @@
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static const char *verstr = "20080224";
+static const char *verstr = "20080504";
 
 #include <linux/module.h>
 
@@ -38,6 +38,7 @@ static const char *verstr = "20080224";
 #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>
@@ -630,7 +631,7 @@ static int cross_eof(struct scsi_tape * STp, int forward)
 /* Flush the write buffer (never need to write if variable blocksize). */
 static int st_flush_write_buffer(struct scsi_tape * STp)
 {
-       int offset, transfer, blks;
+       int transfer, blks;
        int result;
        unsigned char cmd[MAX_COMMAND_SIZE];
        struct st_request *SRpnt;
@@ -643,14 +644,10 @@ static int st_flush_write_buffer(struct scsi_tape * STp)
        result = 0;
        if (STp->dirty == 1) {
 
-               offset = (STp->buffer)->buffer_bytes;
-               transfer = ((offset + STp->block_size - 1) /
-                           STp->block_size) * STp->block_size;
+               transfer = STp->buffer->buffer_bytes;
                 DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n",
                                tape_name(STp), transfer));
 
-               memset((STp->buffer)->b_data + offset, 0, transfer - offset);
-
                memset(cmd, 0, MAX_COMMAND_SIZE);
                cmd[0] = WRITE_6;
                cmd[1] = 1;
@@ -1113,7 +1110,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
 }
 
 
-\f/* Open the device. Needs to be called with BKL only because of incrementing the SCSI host
+\f/* Open the device. Needs to take the BKL only because of incrementing the SCSI host
    module count. */
 static int st_open(struct inode *inode, struct file *filp)
 {
@@ -1123,6 +1120,7 @@ static int st_open(struct inode *inode, struct file *filp)
        int dev = TAPE_NR(inode);
        char *name;
 
+       lock_kernel();
        /*
         * 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
@@ -1130,8 +1128,10 @@ static int st_open(struct inode *inode, struct file *filp)
         */
        filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
 
-       if (!(STp = scsi_tape_get(dev)))
+       if (!(STp = scsi_tape_get(dev))) {
+               unlock_kernel();
                return -ENXIO;
+       }
 
        write_lock(&st_dev_arr_lock);
        filp->private_data = STp;
@@ -1140,6 +1140,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();
                DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); )
                return (-EBUSY);
        }
@@ -1188,12 +1189,14 @@ static int st_open(struct inode *inode, struct file *filp)
                        retval = (-EIO);
                goto err_out;
        }
+       unlock_kernel();
        return 0;
 
  err_out:
        normalize_buffer(STp->buffer);
        STp->in_use = 0;
        scsi_tape_put(STp);
+       unlock_kernel();
        return retval;
 
 }
@@ -1663,6 +1666,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
                                if (undone <= do_count) {
                                        /* Only data from this write is not written */
                                        count += undone;
+                                       b_point -= undone;
                                        do_count -= undone;
                                        if (STp->block_size)
                                                blks = (transfer - undone) / STp->block_size;
@@ -3259,7 +3263,8 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
         * may try and take the device offline, in which case all further
         * access to the device is prohibited.
         */
-       retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p, file);
+       retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p,
+                                       file->f_flags & O_NDELAY);
        if (!scsi_block_when_processing_errors(STp->device) || retval != -ENODEV)
                goto out;
        retval = 0;
@@ -3563,8 +3568,8 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
                            !capable(CAP_SYS_RAWIO))
                                i = -EPERM;
                        else
-                               i = scsi_cmd_ioctl(file, STp->disk->queue,
-                                                  STp->disk, cmd_in, p);
+                               i = scsi_cmd_ioctl(STp->disk->queue, STp->disk,
+                                                  file->f_mode, cmd_in, p);
                        if (i != -ENOTTY)
                                return i;
                        break;
@@ -4424,13 +4429,10 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
                snprintf(name, 10, "%s%s%s", rew ? "n" : "",
                         STp->disk->disk_name, st_formats[i]);
                st_class_member =
-                       device_create_drvdata(st_sysfs_class,
-                                             &STp->device->sdev_gendev,
-                                             MKDEV(SCSI_TAPE_MAJOR,
-                                                   TAPE_MINOR(dev_num,
-                                                             mode, rew)),
-                                             &STp->modes[mode],
-                                             "%s", name);
+                       device_create(st_sysfs_class, &STp->device->sdev_gendev,
+                                     MKDEV(SCSI_TAPE_MAJOR,
+                                           TAPE_MINOR(dev_num, mode, rew)),
+                                     &STp->modes[mode], "%s", name);
                if (IS_ERR(st_class_member)) {
                        printk(KERN_WARNING "st%d: device_create failed\n",
                               dev_num);