Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[safe/jmp/linux-2.6] / drivers / ide / ide-tape.c
index 3468ece..b072328 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/genhd.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
@@ -155,7 +156,8 @@ typedef struct ide_tape_obj {
         * other device. Note that at most we will have only one DSC (usually
         * data transfer) request in the device request queue.
         */
-       struct request *postponed_rq;
+       bool postponed_rq;
+
        /* The time in which we started polling for DSC */
        unsigned long dsc_polling_start;
        /* Timer used to poll for dsc */
@@ -219,6 +221,8 @@ typedef struct ide_tape_obj {
 
 static DEFINE_MUTEX(idetape_ref_mutex);
 
+static DEFINE_MUTEX(idetape_chrdev_mutex);
+
 static struct class *idetape_sysfs_class;
 
 static void ide_tape_release(struct device *);
@@ -372,15 +376,14 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
  * Postpone the current request so that ide.c will be able to service requests
  * from another device on the same port while we are polling for DSC.
  */
-static void idetape_postpone_request(ide_drive_t *drive)
+static void ide_tape_stall_queue(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
-       struct request *rq = drive->hwif->rq;
 
        ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc_poll_freq: %lu",
-                     rq->cmd[0], tape->dsc_poll_freq);
+                     drive->hwif->rq->cmd[0], tape->dsc_poll_freq);
 
-       tape->postponed_rq = rq;
+       tape->postponed_rq = true;
 
        ide_stall_queue(drive, tape->dsc_poll_freq);
 }
@@ -394,7 +397,7 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
        tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST;
        tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
        /* Allow ide.c to handle other requests */
-       idetape_postpone_request(drive);
+       ide_tape_stall_queue(drive);
 }
 
 /*
@@ -567,7 +570,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
        ide_hwif_t *hwif = drive->hwif;
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc *pc = NULL;
-       struct request *postponed_rq = tape->postponed_rq;
        struct ide_cmd cmd;
        u8 stat;
 
@@ -583,18 +585,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                goto out;
        }
 
-       if (postponed_rq != NULL)
-               if (rq != postponed_rq) {
-                       printk(KERN_ERR "ide-tape: ide-tape.c bug - "
-                                       "Two DSC requests were queued\n");
-                       drive->failed_pc = NULL;
-                       rq->errors = 0;
-                       ide_complete_rq(drive, 0, blk_rq_bytes(rq));
-                       return ide_stopped;
-               }
-
-       tape->postponed_rq = NULL;
-
        /*
         * If the tape is still busy, postpone our request and service
         * the other device meanwhile.
@@ -612,7 +602,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
 
        if (!(drive->atapi_flags & IDE_AFLAG_IGNORE_DSC) &&
            !(stat & ATA_DSC)) {
-               if (postponed_rq == NULL) {
+               if (!tape->postponed_rq) {
                        tape->dsc_polling_start = jiffies;
                        tape->dsc_poll_freq = tape->best_dsc_rw_freq;
                        tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT;
@@ -629,10 +619,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
                                        tape->dsc_polling_start +
                                        IDETAPE_DSC_MA_THRESHOLD))
                        tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW;
-               idetape_postpone_request(drive);
+               ide_tape_stall_queue(drive);
                return ide_stopped;
-       } else
+       } else {
                drive->atapi_flags &= ~IDE_AFLAG_IGNORE_DSC;
+               tape->postponed_rq = false;
+       }
 
        if (rq->cmd[13] & REQ_IDETAPE_READ) {
                pc = &tape->queued_pc;
@@ -1373,7 +1365,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
  * supported here, and not in the corresponding block interface. Our own
  * ide-tape ioctls are supported on both interfaces.
  */
-static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
+static long do_idetape_chrdev_ioctl(struct file *file,
                                unsigned int cmd, unsigned long arg)
 {
        struct ide_tape_obj *tape = file->private_data;
@@ -1428,6 +1420,16 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
        }
 }
 
+static long idetape_chrdev_ioctl(struct file *file,
+                               unsigned int cmd, unsigned long arg)
+{
+       long ret;
+       lock_kernel();
+       ret = do_idetape_chrdev_ioctl(file, cmd, arg);
+       unlock_kernel();
+       return ret;
+}
+
 /*
  * Do a mode sense page 0 with block descriptor and if it succeeds set the tape
  * block size with the reported value.
@@ -1467,10 +1469,11 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
        if (i >= MAX_HWIFS * MAX_DRIVES)
                return -ENXIO;
 
-       lock_kernel();
+       mutex_lock(&idetape_chrdev_mutex);
+
        tape = ide_tape_get(NULL, true, i);
        if (!tape) {
-               unlock_kernel();
+               mutex_unlock(&idetape_chrdev_mutex);
                return -ENXIO;
        }
 
@@ -1529,12 +1532,15 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
                                tape->door_locked = DOOR_LOCKED;
                }
        }
-       unlock_kernel();
+       mutex_unlock(&idetape_chrdev_mutex);
+
        return 0;
 
 out_put_tape:
        ide_tape_put(tape);
-       unlock_kernel();
+
+       mutex_unlock(&idetape_chrdev_mutex);
+
        return retval;
 }
 
@@ -1561,7 +1567,8 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
        ide_drive_t *drive = tape->drive;
        unsigned int minor = iminor(inode);
 
-       lock_kernel();
+       mutex_lock(&idetape_chrdev_mutex);
+
        tape = drive->driver_data;
 
        ide_debug_log(IDE_DBG_FUNC, "enter");
@@ -1585,7 +1592,9 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
        }
        clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags);
        ide_tape_put(tape);
-       unlock_kernel();
+
+       mutex_unlock(&idetape_chrdev_mutex);
+
        return 0;
 }
 
@@ -1827,22 +1836,32 @@ static void ide_tape_release(struct device *dev)
 }
 
 #ifdef CONFIG_IDE_PROC_FS
-static int proc_idetape_read_name
-       (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int idetape_name_proc_show(struct seq_file *m, void *v)
 {
-       ide_drive_t     *drive = (ide_drive_t *) data;
+       ide_drive_t     *drive = (ide_drive_t *) m->private;
        idetape_tape_t  *tape = drive->driver_data;
-       char            *out = page;
-       int             len;
 
-       len = sprintf(out, "%s\n", tape->name);
-       PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+       seq_printf(m, "%s\n", tape->name);
+       return 0;
+}
+
+static int idetape_name_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, idetape_name_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations idetape_name_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = idetape_name_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 static ide_proc_entry_t idetape_proc[] = {
-       { "capacity",   S_IFREG|S_IRUGO,        proc_ide_read_capacity, NULL },
-       { "name",       S_IFREG|S_IRUGO,        proc_idetape_read_name, NULL },
-       { NULL, 0, NULL, NULL }
+       { "capacity",   S_IFREG|S_IRUGO,        &ide_capacity_proc_fops },
+       { "name",       S_IFREG|S_IRUGO,        &idetape_name_proc_fops },
+       {}
 };
 
 static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive)
@@ -1879,7 +1898,7 @@ static const struct file_operations idetape_fops = {
        .owner          = THIS_MODULE,
        .read           = idetape_chrdev_read,
        .write          = idetape_chrdev_write,
-       .ioctl          = idetape_chrdev_ioctl,
+       .unlocked_ioctl = idetape_chrdev_ioctl,
        .open           = idetape_chrdev_open,
        .release        = idetape_chrdev_release,
 };
@@ -1913,7 +1932,7 @@ static int idetape_ioctl(struct block_device *bdev, fmode_t mode,
        return err;
 }
 
-static struct block_device_operations idetape_block_ops = {
+static const struct block_device_operations idetape_block_ops = {
        .owner          = THIS_MODULE,
        .open           = idetape_open,
        .release        = idetape_release,