Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
[pandora-kernel.git] / drivers / scsi / 3w-9xxx.c
index e9788f5..e20b7bd 100644 (file)
@@ -1,10 +1,11 @@
 /*
    3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux.
 
-   Written By: Adam Radford <linuxraid@amcc.com>
-   Modifications By: Tom Couch <linuxraid@amcc.com>
+   Written By: Adam Radford <linuxraid@lsi.com>
+   Modifications By: Tom Couch <linuxraid@lsi.com>
 
    Copyright (C) 2004-2009 Applied Micro Circuits Corporation.
+   Copyright (C) 2010 LSI Corporation.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
    Bugs/Comments/Suggestions should be mailed to:
-   linuxraid@amcc.com
+   linuxraid@lsi.com
 
    For more information, goto:
-   http://www.amcc.com
+   http://www.lsi.com
 
    Note: This version of the driver does not contain a bundled firmware
          image.
@@ -77,6 +78,7 @@
                  Use pci_resource_len() for ioremap().
    2.26.02.012 - Add power management support.
    2.26.02.013 - Fix bug in twa_load_sgl().
+   2.26.02.014 - Force 60 second timeout default.
 */
 
 #include <linux/module.h>
 #include "3w-9xxx.h"
 
 /* Globals */
-#define TW_DRIVER_VERSION "2.26.02.013"
+#define TW_DRIVER_VERSION "2.26.02.014"
 static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
 static unsigned int twa_device_extension_count;
 static int twa_major = -1;
 extern struct timezone sys_tz;
 
 /* Module parameters */
-MODULE_AUTHOR ("AMCC");
+MODULE_AUTHOR ("LSI");
 MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(TW_DRIVER_VERSION);
@@ -123,7 +125,7 @@ static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_H
 static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
 static char *twa_aen_severity_lookup(unsigned char severity_code);
 static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id);
-static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 static int twa_chrdev_open(struct inode *inode, struct file *file);
 static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host);
 static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id);
@@ -218,7 +220,7 @@ static struct device_attribute *twa_host_attrs[] = {
 /* File operations struct for character device */
 static const struct file_operations twa_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = twa_chrdev_ioctl,
+       .unlocked_ioctl = twa_chrdev_ioctl,
        .open           = twa_chrdev_open,
        .release        = NULL
 };
@@ -635,8 +637,9 @@ out:
 } /* End twa_check_srl() */
 
 /* This function handles ioctl for the character device */
-static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
+       struct inode *inode = file->f_path.dentry->d_inode;
        long timeout;
        unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
        dma_addr_t dma_handle;
@@ -655,6 +658,8 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
        int retval = TW_IOCTL_ERROR_OS_EFAULT;
        void __user *argp = (void __user *)arg;
 
+       lock_kernel();
+
        /* Only let one of these through at a time */
        if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
                retval = TW_IOCTL_ERROR_OS_EINTR;
@@ -874,6 +879,7 @@ out3:
 out2:
        mutex_unlock(&tw_dev->ioctl_lock);
 out:
+       unlock_kernel();
        return retval;
 } /* End twa_chrdev_ioctl() */
 
@@ -1990,6 +1996,15 @@ static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
                scsi_dma_unmap(cmd);
 } /* End twa_unmap_scsi_data() */
 
+/* This function gets called when a disk is coming on-line */
+static int twa_slave_configure(struct scsi_device *sdev)
+{
+       /* Force 60 second timeout */
+       blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
+
+       return 0;
+} /* End twa_slave_configure() */
+
 /* scsi_host_template initializer */
 static struct scsi_host_template driver_template = {
        .module                 = THIS_MODULE,
@@ -1999,6 +2014,7 @@ static struct scsi_host_template driver_template = {
        .bios_param             = twa_scsi_biosparam,
        .change_queue_depth     = twa_change_queue_depth,
        .can_queue              = TW_Q_LENGTH-2,
+       .slave_configure        = twa_slave_configure,
        .this_id                = -1,
        .sg_tablesize           = TW_APACHE_MAX_SGL_LENGTH,
        .max_sectors            = TW_MAX_SECTORS,