Merge git://oss.sgi.com:8090/xfs/xfs-2.6
[linux-drm-fsl-dcu.git] / drivers / scsi / st.c
index e1a52c525ed492155a8243722e4387428198548b..16e279be4a3e17dd4422192ffa473b9b285d15a1 100644 (file)
@@ -9,7 +9,7 @@
    Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
    Michael Schaefer, J"org Weule, and Eric Youngdale.
 
-   Copyright 1992 - 2005 Kai Makisara
+   Copyright 1992 - 2007 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 = "20050830";
+static const char *verstr = "20070203";
 
 #include <linux/module.h>
 
@@ -922,7 +922,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
        struct st_modedef *STm;
        struct st_partstat *STps;
        char *name = tape_name(STp);
-       struct inode *inode = filp->f_dentry->d_inode;
+       struct inode *inode = filp->f_path.dentry->d_inode;
        int mode = TAPE_MODE(inode);
 
        STp->ready = ST_READY;
@@ -999,7 +999,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
                        STp->min_block = ((STp->buffer)->b_data[4] << 8) |
                            (STp->buffer)->b_data[5];
                        if ( DEB( debugging || ) !STp->inited)
-                               printk(KERN_WARNING
+                               printk(KERN_INFO
                                        "%s: Block limits %d - %d bytes.\n", name,
                                        STp->min_block, STp->max_block);
                } else {
@@ -1168,6 +1168,7 @@ static int st_open(struct inode *inode, struct file *filp)
                STps = &(STp->ps[i]);
                STps->rw = ST_IDLE;
        }
+       STp->try_dio_now = STp->try_dio;
        STp->recover_count = 0;
        DEB( STp->nbr_waits = STp->nbr_finished = 0;
             STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; )
@@ -1224,7 +1225,7 @@ static int st_flush(struct file *filp, fl_owner_t id)
        }
 
        DEBC( if (STp->nbr_requests)
-               printk(KERN_WARNING "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n",
+               printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n",
                       name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable));
 
        if (STps->rw == ST_WRITING && !STp->pos_unknown) {
@@ -1400,9 +1401,9 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
        struct st_buffer *STbp = STp->buffer;
 
        if (is_read)
-               i = STp->try_dio && try_rdio;
+               i = STp->try_dio_now && try_rdio;
        else
-               i = STp->try_dio && try_wdio;
+               i = STp->try_dio_now && try_wdio;
 
        if (i && ((unsigned long)buf & queue_dma_alignment(
                                        STp->device->request_queue)) == 0) {
@@ -1599,7 +1600,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
                        STm->do_async_writes && STps->eof < ST_EOM_OK;
 
                if (STp->block_size != 0 && STm->do_buffer_writes &&
-                   !(STp->try_dio && try_wdio) && STps->eof < ST_EOM_OK &&
+                   !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
                    STbp->buffer_bytes < STbp->buffer_size) {
                        STp->dirty = 1;
                        /* Don't write a buffer that is not full enough. */
@@ -1769,7 +1770,7 @@ static long read_tape(struct scsi_tape *STp, long count,
        if (STp->block_size == 0)
                blks = bytes = count;
        else {
-               if (!(STp->try_dio && try_rdio) && STm->do_read_ahead) {
+               if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
                        blks = (STp->buffer)->buffer_blocks;
                        bytes = blks * STp->block_size;
                } else {
@@ -1948,10 +1949,12 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
                goto out;
 
        STm = &(STp->modes[STp->current_mode]);
-       if (!(STm->do_read_ahead) && STp->block_size != 0 &&
-           (count % STp->block_size) != 0) {
-               retval = (-EINVAL);     /* Read must be integral number of blocks */
-               goto out;
+       if (STp->block_size != 0 && (count % STp->block_size) != 0) {
+               if (!STm->do_read_ahead) {
+                       retval = (-EINVAL);     /* Read must be integral number of blocks */
+                       goto out;
+               }
+               STp->try_dio_now = 0;  /* Direct i/o can't handle split blocks */
        }
 
        STps = &(STp->ps[STp->partition]);
@@ -2816,15 +2819,18 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
 
                if (cmd_in == MTWEOF &&
                    cmdstatp->have_sense &&
-                   (cmdstatp->flags & SENSE_EOM) &&
-                   (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
-                    cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
-                   undone == 0) {
-                       ioctl_result = 0;       /* EOF written successfully at EOM */
-                       if (fileno >= 0)
-                               fileno++;
+                   (cmdstatp->flags & SENSE_EOM)) {
+                       if (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
+                           cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) {
+                               ioctl_result = 0;       /* EOF(s) written successfully at EOM */
+                               STps->eof = ST_NOEOF;
+                       } else {  /* Writing EOF(s) failed */
+                               if (fileno >= 0)
+                                       fileno -= undone;
+                               if (undone < arg)
+                                       STps->eof = ST_NOEOF;
+                       }
                        STps->drv_file = fileno;
-                       STps->eof = ST_NOEOF;
                } else if ((cmd_in == MTFSF) || (cmd_in == MTFSFM)) {
                        if (fileno >= 0)
                                STps->drv_file = fileno - undone;
@@ -4056,11 +4062,11 @@ static int st_probe(struct device *dev)
                        goto out_free_tape;
        }
 
-       sdev_printk(KERN_WARNING, SDp,
+       sdev_printk(KERN_NOTICE, SDp,
                    "Attached scsi tape %s\n", tape_name(tpnt));
-       printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
-              tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
-              queue_dma_alignment(SDp->request_queue) + 1);
+       sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n",
+                   tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
+                   queue_dma_alignment(SDp->request_queue) + 1);
 
        return 0;