Push down the bkl into ioctl functions on the scsi layer.
[jkacur: Forward declaration missing ';'.
Conflicting declaraction in megaraid.h changed
Fixed missing inodes declarations]
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: John Kacur <jkacur@redhat.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
 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);
 /* 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
 };
 } /* 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;
        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;
 out2:
        mutex_unlock(&tw_dev->ioctl_lock);
 out:
+       unlock_kernel();
        return retval;
 } /* End twa_chrdev_ioctl() */
 
 
 
 /* This function handles ioctl for the character device
    This interface is used by smartmontools open source software */
-static int twl_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        long timeout;
        unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
        dma_addr_t dma_handle;
        int request_id = 0;
        TW_Ioctl_Driver_Command driver_command;
+       struct inode *inode = file->f_dentry->d_inode;
        TW_Ioctl_Buf_Apache *tw_ioctl;
        TW_Command_Full *full_command_packet;
        TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
        int retval = -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 = -EINTR;
 out2:
        mutex_unlock(&tw_dev->ioctl_lock);
 out:
+       unlock_kernel();
        return retval;
 } /* End twl_chrdev_ioctl() */
 
 /* File operations struct for character device */
 static const struct file_operations twl_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = twl_chrdev_ioctl,
+       .unlocked_ioctl = twl_chrdev_ioctl,
        .open           = twl_chrdev_open,
        .release        = NULL
 };
 
 } /* End tw_allocate_memory() */
 
 /* This function handles ioctl for the character device */
-static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        int request_id;
        dma_addr_t dma_handle;
        unsigned long flags;
        unsigned int data_buffer_length = 0;
        unsigned long data_buffer_length_adjusted = 0;
+       struct inode *inode = file->f_dentry->d_inode;
        unsigned long *cpu_addr;
        long timeout;
        TW_New_Ioctl *tw_ioctl;
 
        dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
 
+       lock_kernel();
        /* Only let one of these through at a time */
-       if (mutex_lock_interruptible(&tw_dev->ioctl_lock))
+       if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
+               unlock_kernel();
                return -EINTR;
+       }
 
        /* First copy down the buffer length */
        if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int)))
        dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
 out:
        mutex_unlock(&tw_dev->ioctl_lock);
+       unlock_kernel();
        return retval;
 } /* End tw_chrdev_ioctl() */
 
 /* File operations struct for character device */
 static const struct file_operations tw_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = tw_chrdev_ioctl,
+       .unlocked_ioctl = tw_chrdev_ioctl,
        .open           = tw_chrdev_open,
        .release        = NULL
 };
 
  *     Bugs: Needs to handle hot plugging
  */
 
-static int aac_cfg_ioctl(struct inode *inode, struct file *file,
+static long aac_cfg_ioctl(struct file *file,
                unsigned int cmd, unsigned long arg)
 {
+       int ret;
        if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
-       return aac_do_ioctl(file->private_data, cmd, (void __user *)arg);
+       lock_kernel();
+       ret = aac_do_ioctl(file->private_data, cmd, (void __user *)arg);
+       unlock_kernel();
+
+       return ret;
 }
 
 #ifdef CONFIG_COMPAT
 
 static const struct file_operations aac_cfg_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = aac_cfg_ioctl,
+       .unlocked_ioctl = aac_cfg_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = aac_compat_cfg_ioctl,
 #endif
 
 
 static struct class *adpt_sysfs_class;
 
+static long adpt_unlocked_ioctl(struct file *, unsigned int, unsigned long);
 #ifdef CONFIG_COMPAT
 static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long);
 #endif
 
 static const struct file_operations adpt_fops = {
-       .ioctl          = adpt_ioctl,
+       .unlocked_ioctl = adpt_unlocked_ioctl,
        .open           = adpt_open,
        .release        = adpt_close,
 #ifdef CONFIG_COMPAT
        return 0;
 }
 
-static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
-             ulong arg)
+static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
 {
        int minor;
        int error = 0;
        return error;
 }
 
+static long adpt_unlocked_ioctl(struct file *file, uint cmd, ulong arg)
+{
+       struct inode *inode;
+       long ret;
+ 
+       inode = file->f_dentry->d_inode;
+ 
+       lock_kernel();
+       ret = adpt_ioctl(inode, file, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
 #ifdef CONFIG_COMPAT
 static long compat_adpt_ioctl(struct file *file,
                                unsigned int cmd, unsigned long arg)
 
 
 static int gdth_open(struct inode *inode, struct file *filep);
 static int gdth_close(struct inode *inode, struct file *filep);
-static int gdth_ioctl(struct inode *inode, struct file *filep,
-                      unsigned int cmd, unsigned long arg);
+static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd,
+                               unsigned long arg);
 
 static void gdth_flush(gdth_ha_str *ha);
 static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *));
 
 /* ioctl interface */
 static const struct file_operations gdth_fops = {
-    .ioctl   = gdth_ioctl,
+    .unlocked_ioctl   = gdth_unlocked_ioctl,
     .open    = gdth_open,
     .release = gdth_close,
 };
     return rc;
 }
   
-static int gdth_ioctl(struct inode *inode, struct file *filep,
-                      unsigned int cmd, unsigned long arg)
+static int gdth_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
     gdth_ha_str *ha; 
     Scsi_Cmnd *scp;
     return 0;
 }
 
+static long gdth_unlocked_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
+{
+       int ret;
+
+       lock_kernel();
+       ret = gdth_ioctl(file, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
 
 /* flush routine */
 static void gdth_flush(gdth_ha_str *ha)
 
 /* For controller re-ordering */
 static struct mega_hbas mega_hbas[MAX_CONTROLLERS];
 
+static long
+megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
+
 /*
  * The File Operations structure for the serial/ioctl interface of the driver
  */
 static const struct file_operations megadev_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = megadev_ioctl,
+       .unlocked_ioctl = megadev_unlocked_ioctl,
        .open           = megadev_open,
 };
 
  * controller.
  */
 static int
-megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
-               unsigned long arg)
+megadev_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
        adapter_t       *adapter;
        nitioctl_t      uioc;
        return 0;
 }
 
+static long
+megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+       int ret;
+
+       lock_kernel();
+       ret = megadev_ioctl(filep, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
 /**
  * mega_m_to_n()
  * @arg - user address
 
                mega_inquiry3 *enquiry3, mega_product_info *);
 
 static int megadev_open (struct inode *, struct file *);
-static int megadev_ioctl (struct inode *, struct file *, unsigned int,
-               unsigned long);
+static int megadev_ioctl (struct file *, unsigned int, unsigned long);
 static int mega_m_to_n(void __user *, nitioctl_t *);
 static int mega_n_to_m(void __user *, megacmd_t *);
 
 
 
 // Entry points for char node driver
 static int mraid_mm_open(struct inode *, struct file *);
-static int mraid_mm_ioctl(struct inode *, struct file *, uint, unsigned long);
+static long mraid_mm_unlocked_ioctl(struct file *, uint, unsigned long);
 
 
 // routines to convert to and from the old the format
 
 static const struct file_operations lsi_fops = {
        .open   = mraid_mm_open,
-       .ioctl  = mraid_mm_ioctl,
+       .unlocked_ioctl = mraid_mm_unlocked_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = mraid_mm_compat_ioctl,
 #endif
  * @arg                : user ioctl packet
  */
 static int
-mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
-                                                       unsigned long arg)
+mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
        uioc_t          *kioc;
        char            signature[EXT_IOCTL_SIGN_SZ]    = {0};
        return rval;
 }
 
+static long
+mraid_mm_unlocked_ioctl(struct file *filep, unsigned int cmd,
+                       unsigned long arg)
+{
+       int err;
+
+       /* inconsistant: mraid_mm_compat_ioctl doesn't take the BKL */
+       lock_kernel();
+       err = mraid_mm_ioctl(filep, cmd, arg);
+       unlock_kernel();
+
+       return err;
+}
 
 /**
  * mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet
 {
        int err;
 
-       err = mraid_mm_ioctl(NULL, filep, cmd, arg);
+       err = mraid_mm_ioctl(filep, cmd, arg);
 
        return err;
 }
 
 
 
 /* The ioctl command */
-static int osst_ioctl(struct inode * inode,struct file * file,
+static long osst_ioctl(struct file * file,
         unsigned int cmd_in, unsigned long arg)
 {
        int                   i, cmd_nr, cmd_type, blk, retval = 0;
        char                * name  = tape_name(STp);
        void        __user  * p     = (void __user *)arg;
 
-       if (mutex_lock_interruptible(&STp->lock))
+       lock_kernel();
+       if (mutex_lock_interruptible(&STp->lock)) {
+               unlock_kernel();
                return -ERESTARTSYS;
+       }
 
 #if DEBUG
        if (debugging && !STp->in_use) {
 
        mutex_unlock(&STp->lock);
 
-       return scsi_ioctl(STp->device, cmd_in, p);
+       retval = scsi_ioctl(STp->device, cmd_in, p);
+       unlock_kernel();
+       return retval;
 
 out:
        if (SRpnt) osst_release_request(SRpnt);
 
        mutex_unlock(&STp->lock);
+       unlock_kernel();
 
        return retval;
 }
        .owner =        THIS_MODULE,
        .read =         osst_read,
        .write =        osst_write,
-       .ioctl =        osst_ioctl,
+       .unlocked_ioctl = osst_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = osst_compat_ioctl,
 #endif
 
 }
 
 static int
-sg_ioctl(struct inode *inode, struct file *filp,
-        unsigned int cmd_in, unsigned long arg)
+sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
 {
        void __user *p = (void __user *)arg;
        int __user *ip = p;
        }
 }
 
+static long
+sg_unlocked_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
+{
+       int ret;
+
+       lock_kernel();
+       ret = sg_ioctl(filp, cmd_in, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
 #ifdef CONFIG_COMPAT
 static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
 {
        .read = sg_read,
        .write = sg_write,
        .poll = sg_poll,
-       .ioctl = sg_ioctl,
+       .unlocked_ioctl = sg_unlocked_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = sg_compat_ioctl,
 #endif