Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Jul 2008 21:48:31 +0000 (14:48 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 14 Jul 2008 21:48:31 +0000 (14:48 -0700)
* 'bkl-removal' of git://git.lwn.net/linux-2.6: (146 commits)
  IB/umad: BKL is not needed for ib_umad_open()
  IB/uverbs: BKL is not needed for ib_uverbs_open()
  bf561-coreb: BKL unneeded for open()
  Call fasync() functions without the BKL
  snd/PCM: fasync BKL pushdown
  ipmi: fasync BKL pushdown
  ecryptfs: fasync BKL pushdown
  Bluetooth VHCI: fasync BKL pushdown
  tty_io: fasync BKL pushdown
  tun: fasync BKL pushdown
  i2o: fasync BKL pushdown
  mpt: fasync BKL pushdown
  Remove BKL from remote_llseek v2
  Make FAT users happier by not deadlocking
  x86-mce: BKL pushdown
  vmwatchdog: BKL pushdown
  vmcp: BKL pushdown
  via-pmu: BKL pushdown
  uml-random: BKL pushdown
  uml-mmapper: BKL pushdown
  ...

17 files changed:
1  2 
arch/s390/crypto/prng.c
arch/x86/kernel/apm_32.c
arch/x86/kernel/cpu/mcheck/mce_64.c
arch/x86/kernel/microcode.c
block/bsg.c
drivers/block/paride/pt.c
drivers/gpu/drm/drm_fops.c
drivers/pcmcia/pcmcia_ioctl.c
drivers/s390/char/fs3270.c
drivers/s390/char/monreader.c
drivers/s390/char/vmcp.c
drivers/s390/char/vmlogrdr.c
drivers/s390/char/vmur.c
drivers/s390/char/vmwatchdog.c
drivers/s390/crypto/zcrypt_api.c
drivers/scsi/sg.c
sound/core/sound.c

diff --combined arch/s390/crypto/prng.c
@@@ -6,6 -6,7 +6,7 @@@
  #include <linux/fs.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
+ #include <linux/smp_lock.h>
  #include <linux/miscdevice.h>
  #include <linux/module.h>
  #include <linux/moduleparam.h>
@@@ -48,6 -49,7 +49,7 @@@ static unsigned char parm_block[32] = 
  
  static int prng_open(struct inode *inode, struct file *file)
  {
+       cycle_kernel_lock();
        return nonseekable_open(inode, file);
  }
  
@@@ -185,8 -187,11 +187,8 @@@ static int __init prng_init(void
        prng_seed(16);
  
        ret = misc_register(&prng_dev);
 -      if (ret) {
 -              printk(KERN_WARNING
 -                     "Could not register misc device for PRNG.\n");
 +      if (ret)
                goto out_buf;
 -      }
        return 0;
  
  out_buf:
diff --combined arch/x86/kernel/apm_32.c
  #include <linux/module.h>
  
  #include <linux/poll.h>
+ #include <linux/smp_lock.h>
  #include <linux/types.h>
  #include <linux/stddef.h>
  #include <linux/timer.h>
  #include <linux/suspend.h>
  #include <linux/kthread.h>
  #include <linux/jiffies.h>
 +#include <linux/smp_lock.h>
  
  #include <asm/system.h>
  #include <asm/uaccess.h>
@@@ -1150,7 -1150,7 +1151,7 @@@ static void queue_event(apm_event_t eve
                                as->event_tail = 0;
                }
                as->events[as->event_head] = event;
 -              if ((!as->suser) || (!as->writer))
 +              if (!as->suser || !as->writer)
                        continue;
                switch (event) {
                case APM_SYS_SUSPEND:
@@@ -1397,7 -1397,7 +1398,7 @@@ static void apm_mainloop(void
  
  static int check_apm_user(struct apm_user *as, const char *func)
  {
 -      if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
 +      if (as == NULL || as->magic != APM_BIOS_MAGIC) {
                printk(KERN_ERR "apm: %s passed bad filp\n", func);
                return 1;
        }
@@@ -1460,19 -1460,18 +1461,19 @@@ static unsigned int do_poll(struct fil
        return 0;
  }
  
 -static int do_ioctl(struct inode *inode, struct file *filp,
 -                  u_int cmd, u_long arg)
 +static long do_ioctl(struct file *filp, u_int cmd, u_long arg)
  {
        struct apm_user *as;
 +      int ret;
  
        as = filp->private_data;
        if (check_apm_user(as, "ioctl"))
                return -EIO;
 -      if ((!as->suser) || (!as->writer))
 +      if (!as->suser || !as->writer)
                return -EPERM;
        switch (cmd) {
        case APM_IOC_STANDBY:
 +              lock_kernel();
                if (as->standbys_read > 0) {
                        as->standbys_read--;
                        as->standbys_pending--;
                        queue_event(APM_USER_STANDBY, as);
                if (standbys_pending <= 0)
                        standby();
 +              unlock_kernel();
                break;
        case APM_IOC_SUSPEND:
 +              lock_kernel();
                if (as->suspends_read > 0) {
                        as->suspends_read--;
                        as->suspends_pending--;
                } else
                        queue_event(APM_USER_SUSPEND, as);
                if (suspends_pending <= 0) {
 -                      return suspend(1);
 +                      ret = suspend(1);
                } else {
                        as->suspend_wait = 1;
                        wait_event_interruptible(apm_suspend_waitqueue,
                                        as->suspend_wait == 0);
 -                      return as->suspend_result;
 +                      ret = as->suspend_result;
                }
 -              break;
 +              unlock_kernel();
 +              return ret;
        default:
 -              return -EINVAL;
 +              return -ENOTTY;
        }
        return 0;
  }
@@@ -1549,10 -1545,12 +1550,12 @@@ static int do_open(struct inode *inode
  {
        struct apm_user *as;
  
+       lock_kernel();
        as = kmalloc(sizeof(*as), GFP_KERNEL);
        if (as == NULL) {
                printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
                       sizeof(*as));
+                      unlock_kernel();
                return -ENOMEM;
        }
        as->magic = APM_BIOS_MAGIC;
        user_list = as;
        spin_unlock(&user_list_lock);
        filp->private_data = as;
+       unlock_kernel();
        return 0;
  }
  
@@@ -1865,7 -1864,7 +1869,7 @@@ static const struct file_operations apm
        .owner          = THIS_MODULE,
        .read           = do_read,
        .poll           = do_poll,
 -      .ioctl          = do_ioctl,
 +      .unlocked_ioctl = do_ioctl,
        .open           = do_open,
        .release        = do_release,
  };
@@@ -9,6 -9,7 +9,7 @@@
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/sched.h>
+ #include <linux/smp_lock.h>
  #include <linux/string.h>
  #include <linux/rcupdate.h>
  #include <linux/kallsyms.h>
@@@ -31,7 -32,7 +32,7 @@@
  #include <asm/idle.h>
  
  #define MISC_MCELOG_MINOR 227
 -#define NR_BANKS 6
 +#define NR_SYSFS_BANKS 6
  
  atomic_t mce_entry;
  
@@@ -46,7 -47,7 +47,7 @@@ static int mce_dont_init
   */
  static int tolerant = 1;
  static int banks;
 -static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
 +static unsigned long bank[NR_SYSFS_BANKS] = { [0 ... NR_SYSFS_BANKS-1] = ~0UL };
  static unsigned long notify_user;
  static int rip_msr;
  static int mce_bootlog = -1;
@@@ -209,7 -210,7 +210,7 @@@ void do_machine_check(struct pt_regs * 
        barrier();
  
        for (i = 0; i < banks; i++) {
 -              if (!bank[i])
 +              if (i < NR_SYSFS_BANKS && !bank[i])
                        continue;
  
                m.misc = 0;
@@@ -444,10 -445,9 +445,10 @@@ static void mce_init(void *dummy
  
        rdmsrl(MSR_IA32_MCG_CAP, cap);
        banks = cap & 0xff;
 -      if (banks > NR_BANKS) {
 -              printk(KERN_INFO "MCE: warning: using only %d banks\n", banks);
 -              banks = NR_BANKS;
 +      if (banks > MCE_EXTENDED_BANK) {
 +              banks = MCE_EXTENDED_BANK;
 +              printk(KERN_INFO "MCE: warning: using only %d banks\n",
 +                     MCE_EXTENDED_BANK);
        }
        /* Use accurate RIP reporting if available. */
        if ((cap & (1<<9)) && ((cap >> 16) & 0xff) >= 9)
                wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
  
        for (i = 0; i < banks; i++) {
 -              wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]);
 +              if (i < NR_SYSFS_BANKS)
 +                      wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]);
 +              else
 +                      wrmsrl(MSR_IA32_MC0_CTL+4*i, ~0UL);
 +
                wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
        }
  }
@@@ -532,10 -528,12 +533,12 @@@ static int open_exclu;  /* already open 
  
  static int mce_open(struct inode *inode, struct file *file)
  {
+       lock_kernel();
        spin_lock(&mce_state_lock);
  
        if (open_exclu || (open_count && (file->f_flags & O_EXCL))) {
                spin_unlock(&mce_state_lock);
+               unlock_kernel();
                return -EBUSY;
        }
  
        open_count++;
  
        spin_unlock(&mce_state_lock);
+       unlock_kernel();
  
        return nonseekable_open(inode, file);
  }
@@@ -771,10 -770,7 +775,10 @@@ DEFINE_PER_CPU(struct sys_device, devic
        }                                                               \
        static SYSDEV_ATTR(name, 0644, show_ ## name, set_ ## name);
  
 -/* TBD should generate these dynamically based on number of available banks */
 +/*
 + * TBD should generate these dynamically based on number of available banks.
 + * Have only 6 contol banks in /sysfs until then.
 + */
  ACCESSOR(bank0ctl,bank[0],mce_restart())
  ACCESSOR(bank1ctl,bank[1],mce_restart())
  ACCESSOR(bank2ctl,bank[2],mce_restart())
@@@ -5,14 -5,13 +5,14 @@@
   *                  2006      Shaohua Li <shaohua.li@intel.com>
   *
   *    This driver allows to upgrade microcode on Intel processors
 - *    belonging to IA-32 family - PentiumPro, Pentium II, 
 + *    belonging to IA-32 family - PentiumPro, Pentium II,
   *    Pentium III, Xeon, Pentium 4, etc.
   *
 - *    Reference: Section 8.10 of Volume III, Intel Pentium 4 Manual, 
 - *    Order Number 245472 or free download from:
 - *            
 - *    http://developer.intel.com/design/pentium4/manuals/245472.htm
 + *    Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture
 + *    Software Developer's Manual
 + *    Order Number 253668 or free download from:
 + *
 + *    http://developer.intel.com/design/pentium4/manuals/253668.htm
   *
   *    For more information, go to http://www.urbanmyth.org/microcode
   *
   *            nature of implementation.
   *    1.11    22 Mar 2002 Tigran Aivazian <tigran@veritas.com>
   *            Fix the panic when writing zero-length microcode chunk.
 - *    1.12    29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, 
 + *    1.12    29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>,
   *            Jun Nakajima <jun.nakajima@intel.com>
   *            Support for the microcode updates in the new format.
   *    1.13    10 Oct 2003 Tigran Aivazian <tigran@veritas.com>
   *            Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl
 - *            because we no longer hold a copy of applied microcode 
 + *            because we no longer hold a copy of applied microcode
   *            in kernel memory.
   *    1.14    25 Jun 2004 Tigran Aivazian <tigran@veritas.com>
   *            Fix sigmatch() macro to handle old CPUs with pf == 0.
@@@ -76,6 -75,7 +76,7 @@@
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/sched.h>
+ #include <linux/smp_lock.h>
  #include <linux/cpumask.h>
  #include <linux/module.h>
  #include <linux/slab.h>
@@@ -321,11 -321,11 +322,11 @@@ static void apply_microcode(int cpu
                return;
  
        /* serialize access to the physical write to MSR 0x79 */
 -      spin_lock_irqsave(&microcode_update_lock, flags);          
 +      spin_lock_irqsave(&microcode_update_lock, flags);
  
        /* write microcode via MSR 0x79 */
        wrmsr(MSR_IA32_UCODE_WRITE,
 -              (unsigned long) uci->mc->bits, 
 +              (unsigned long) uci->mc->bits,
                (unsigned long) uci->mc->bits >> 16 >> 16);
        wrmsr(MSR_IA32_UCODE_REV, 0, 0);
  
                return;
        }
        printk(KERN_INFO "microcode: CPU%d updated from revision "
 -             "0x%x to 0x%x, date = %08x \n", 
 +             "0x%x to 0x%x, date = %08x \n",
               cpu_num, uci->rev, val[1], uci->mc->hdr.date);
        uci->rev = val[1];
  }
@@@ -423,6 -423,7 +424,7 @@@ out
  
  static int microcode_open (struct inode *unused1, struct file *unused2)
  {
+       cycle_kernel_lock();
        return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
  }
  
@@@ -535,7 -536,7 +537,7 @@@ static int cpu_request_microcode(int cp
                c->x86, c->x86_model, c->x86_mask);
        error = request_firmware(&firmware, name, &microcode_pdev->dev);
        if (error) {
 -              pr_debug("microcode: ucode data file %s load failed\n", name);
 +              pr_debug("microcode: data file %s load failed\n", name);
                return error;
        }
        buf = firmware->data;
@@@ -806,9 -807,6 +808,9 @@@ static int __init microcode_init (void
  {
        int error;
  
 +      printk(KERN_INFO
 +              "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");
 +
        error = microcode_dev_init();
        if (error)
                return error;
        }
  
        register_hotcpu_notifier(&mc_cpu_notifier);
 -
 -      printk(KERN_INFO 
 -              "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@aivazian.fsnet.co.uk>\n");
        return 0;
  }
  
diff --combined block/bsg.c
@@@ -19,6 -19,7 +19,7 @@@
  #include <linux/uio.h>
  #include <linux/idr.h>
  #include <linux/bsg.h>
+ #include <linux/smp_lock.h>
  
  #include <scsi/scsi.h>
  #include <scsi/scsi_ioctl.h>
@@@ -44,12 -45,11 +45,12 @@@ struct bsg_device 
        char name[BUS_ID_SIZE];
        int max_queue;
        unsigned long flags;
 +      struct blk_scsi_cmd_filter *cmd_filter;
 +      mode_t *f_mode;
  };
  
  enum {
        BSG_F_BLOCK             = 1,
 -      BSG_F_WRITE_PERM        = 2,
  };
  
  #define BSG_DEFAULT_CMDS      64
@@@ -173,7 -173,7 +174,7 @@@ unlock
  }
  
  static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
 -                              struct sg_io_v4 *hdr, int has_write_perm)
 +                              struct sg_io_v4 *hdr, struct bsg_device *bd)
  {
        if (hdr->request_len > BLK_MAX_CDB) {
                rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
                return -EFAULT;
  
        if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
 -              if (blk_verify_command(rq->cmd, has_write_perm))
 +              if (blk_cmd_filter_verify_command(bd->cmd_filter, rq->cmd,
 +                                               bd->f_mode))
                        return -EPERM;
        } else if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
@@@ -265,7 -264,8 +266,7 @@@ bsg_map_hdr(struct bsg_device *bd, stru
        rq = blk_get_request(q, rw, GFP_KERNEL);
        if (!rq)
                return ERR_PTR(-ENOMEM);
 -      ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, test_bit(BSG_F_WRITE_PERM,
 -                                                     &bd->flags));
 +      ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd);
        if (ret)
                goto out;
  
@@@ -567,23 -567,12 +568,23 @@@ static inline void bsg_set_block(struc
                set_bit(BSG_F_BLOCK, &bd->flags);
  }
  
 -static inline void bsg_set_write_perm(struct bsg_device *bd, struct file *file)
 +static void bsg_set_cmd_filter(struct bsg_device *bd,
 +                         struct file *file)
  {
 -      if (file->f_mode & FMODE_WRITE)
 -              set_bit(BSG_F_WRITE_PERM, &bd->flags);
 -      else
 -              clear_bit(BSG_F_WRITE_PERM, &bd->flags);
 +      struct inode *inode;
 +      struct gendisk *disk;
 +
 +      if (!file)
 +              return;
 +
 +      inode = file->f_dentry->d_inode;
 +      if (!inode)
 +              return;
 +
 +      disk = inode->i_bdev->bd_disk;
 +
 +      bd->cmd_filter = &disk->cmd_filter;
 +      bd->f_mode = &file->f_mode;
  }
  
  /*
@@@ -607,8 -596,6 +608,8 @@@ bsg_read(struct file *file, char __use
        dprintk("%s: read %Zd bytes\n", bd->name, count);
  
        bsg_set_block(bd, file);
 +      bsg_set_cmd_filter(bd, file);
 +
        bytes_read = 0;
        ret = __bsg_read(buf, count, bd, NULL, &bytes_read);
        *ppos = bytes_read;
@@@ -682,7 -669,7 +683,7 @@@ bsg_write(struct file *file, const cha
        dprintk("%s: write %Zd bytes\n", bd->name, count);
  
        bsg_set_block(bd, file);
 -      bsg_set_write_perm(bd, file);
 +      bsg_set_cmd_filter(bd, file);
  
        bytes_written = 0;
        ret = __bsg_write(bd, buf, count, &bytes_written);
@@@ -786,9 -773,7 +787,9 @@@ static struct bsg_device *bsg_add_devic
        }
  
        bd->queue = rq;
 +
        bsg_set_block(bd, file);
 +      bsg_set_cmd_filter(bd, file);
  
        atomic_set(&bd->ref_count, 1);
        mutex_lock(&bsg_mutex);
@@@ -851,7 -836,11 +852,11 @@@ static struct bsg_device *bsg_get_devic
  
  static int bsg_open(struct inode *inode, struct file *file)
  {
-       struct bsg_device *bd = bsg_get_device(inode, file);
+       struct bsg_device *bd;
+       lock_kernel();
+       bd = bsg_get_device(inode, file);
+       unlock_kernel();
  
        if (IS_ERR(bd))
                return PTR_ERR(bd);
@@@ -190,7 -190,8 +190,7 @@@ module_param_array(drive3, int, NULL, 0
  #define ATAPI_LOG_SENSE               0x4d
  
  static int pt_open(struct inode *inode, struct file *file);
 -static int pt_ioctl(struct inode *inode, struct file *file,
 -                  unsigned int cmd, unsigned long arg);
 +static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
  static int pt_release(struct inode *inode, struct file *file);
  static ssize_t pt_read(struct file *filp, char __user *buf,
                       size_t count, loff_t * ppos);
@@@ -236,7 -237,7 +236,7 @@@ static const struct file_operations pt_
        .owner = THIS_MODULE,
        .read = pt_read,
        .write = pt_write,
 -      .ioctl = pt_ioctl,
 +      .unlocked_ioctl = pt_ioctl,
        .open = pt_open,
        .release = pt_release,
  };
@@@ -650,8 -651,11 +650,11 @@@ static int pt_open(struct inode *inode
        struct pt_unit *tape = pt + unit;
        int err;
  
-       if (unit >= PT_UNITS || (!tape->present))
+       lock_kernel();
+       if (unit >= PT_UNITS || (!tape->present)) {
+               unlock_kernel();
                return -ENODEV;
+       }
  
        err = -EBUSY;
        if (!atomic_dec_and_test(&tape->available))
        }
  
        file->private_data = tape;
+       unlock_kernel();
        return 0;
  
  out:
        atomic_inc(&tape->available);
+       unlock_kernel();
        return err;
  }
  
 -static int pt_ioctl(struct inode *inode, struct file *file,
 -       unsigned int cmd, unsigned long arg)
 +static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  {
        struct pt_unit *tape = file->private_data;
        struct mtop __user *p = (void __user *)arg;
                switch (mtop.mt_op) {
  
                case MTREW:
 +                      lock_kernel();
                        pt_rewind(tape);
 +                      unlock_kernel();
                        return 0;
  
                case MTWEOF:
 +                      lock_kernel();
                        pt_write_fm(tape);
 +                      unlock_kernel();
                        return 0;
  
                default:
 -                      printk("%s: Unimplemented mt_op %d\n", tape->name,
 +                      /* FIXME: rate limit ?? */
 +                      printk(KERN_DEBUG "%s: Unimplemented mt_op %d\n", tape->name,
                               mtop.mt_op);
                        return -EINVAL;
                }
  
        default:
 -              printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd);
 -              return -EINVAL;
 -
 +              return -ENOTTY;
        }
  }
  
@@@ -37,6 -37,7 +37,7 @@@
  #include "drmP.h"
  #include "drm_sarea.h"
  #include <linux/poll.h>
+ #include <linux/smp_lock.h>
  
  static int drm_open_helper(struct inode *inode, struct file *filp,
                           struct drm_device * dev);
@@@ -174,12 -175,14 +175,14 @@@ int drm_stub_open(struct inode *inode, 
  
        DRM_DEBUG("\n");
  
+       /* BKL pushdown: note that nothing else serializes idr_find() */
+       lock_kernel();
        minor = idr_find(&drm_minors_idr, minor_id);
        if (!minor)
-               return -ENODEV;
+               goto out;
  
        if (!(dev = minor->dev))
-               return -ENODEV;
+               goto out;
  
        old_fops = filp->f_op;
        filp->f_op = fops_get(&dev->driver->fops);
        }
        fops_put(old_fops);
  
+ out:
+       unlock_kernel();
        return err;
  }
  
  #include <linux/proc_fs.h>
  #include <linux/poll.h>
  #include <linux/pci.h>
+ #include <linux/smp_lock.h>
  #include <linux/workqueue.h>
  
 -#define IN_CARD_SERVICES
  #include <pcmcia/cs_types.h>
  #include <pcmcia/cs.h>
  #include <pcmcia/cistpl.h>
 +#include <pcmcia/cisreg.h>
  #include <pcmcia/ds.h>
  #include <pcmcia/ss.h>
  
@@@ -138,154 -139,6 +139,154 @@@ static int proc_read_drivers(char *buf
  }
  #endif
  
 +
 +#ifdef CONFIG_PCMCIA_PROBE
 +
 +static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
 +{
 +      int irq;
 +      u32 mask;
 +
 +      irq = adj->resource.irq.IRQ;
 +      if ((irq < 0) || (irq > 15))
 +              return CS_BAD_IRQ;
 +
 +      if (adj->Action != REMOVE_MANAGED_RESOURCE)
 +              return 0;
 +
 +      mask = 1 << irq;
 +
 +      if (!(s->irq_mask & mask))
 +              return 0;
 +
 +      s->irq_mask &= ~mask;
 +
 +      return 0;
 +}
 +
 +#else
 +
 +static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) {
 +      return CS_SUCCESS;
 +}
 +
 +#endif
 +
 +static int pcmcia_adjust_resource_info(adjust_t *adj)
 +{
 +      struct pcmcia_socket *s;
 +      int ret = CS_UNSUPPORTED_FUNCTION;
 +      unsigned long flags;
 +
 +      down_read(&pcmcia_socket_list_rwsem);
 +      list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
 +
 +              if (adj->Resource == RES_IRQ)
 +                      ret = adjust_irq(s, adj);
 +
 +              else if (s->resource_ops->add_io) {
 +                      unsigned long begin, end;
 +
 +                      /* you can't use the old interface if the new
 +                       * one was used before */
 +                      spin_lock_irqsave(&s->lock, flags);
 +                      if ((s->resource_setup_new) &&
 +                          !(s->resource_setup_old)) {
 +                              spin_unlock_irqrestore(&s->lock, flags);
 +                              continue;
 +                      } else if (!(s->resource_setup_old))
 +                              s->resource_setup_old = 1;
 +                      spin_unlock_irqrestore(&s->lock, flags);
 +
 +                      switch (adj->Resource) {
 +                      case RES_MEMORY_RANGE:
 +                              begin = adj->resource.memory.Base;
 +                              end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
 +                              if (s->resource_ops->add_mem)
 +                                      ret =s->resource_ops->add_mem(s, adj->Action, begin, end);
 +                      case RES_IO_RANGE:
 +                              begin = adj->resource.io.BasePort;
 +                              end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
 +                              if (s->resource_ops->add_io)
 +                                      ret = s->resource_ops->add_io(s, adj->Action, begin, end);
 +                      }
 +                      if (!ret) {
 +                              /* as there's no way we know this is the
 +                               * last call to adjust_resource_info, we
 +                               * always need to assume this is the latest
 +                               * one... */
 +                              spin_lock_irqsave(&s->lock, flags);
 +                              s->resource_setup_done = 1;
 +                              spin_unlock_irqrestore(&s->lock, flags);
 +                      }
 +              }
 +      }
 +      up_read(&pcmcia_socket_list_rwsem);
 +
 +      return (ret);
 +}
 +
 +/** pccard_get_status
 + *
 + * Get the current socket state bits.  We don't support the latched
 + * SocketState yet: I haven't seen any point for it.
 + */
 +
 +static int pccard_get_status(struct pcmcia_socket *s,
 +                           struct pcmcia_device *p_dev,
 +                           cs_status_t *status)
 +{
 +      config_t *c;
 +      int val;
 +
 +      s->ops->get_status(s, &val);
 +      status->CardState = status->SocketState = 0;
 +      status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
 +      status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
 +      status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
 +      status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
 +      if (s->state & SOCKET_SUSPEND)
 +              status->CardState |= CS_EVENT_PM_SUSPEND;
 +      if (!(s->state & SOCKET_PRESENT))
 +              return CS_NO_CARD;
 +
 +      c = (p_dev) ? p_dev->function_config : NULL;
 +
 +      if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
 +          (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
 +              u_char reg;
 +              if (c->CardValues & PRESENT_PIN_REPLACE) {
 +                      pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
 +                      status->CardState |=
 +                              (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
 +                      status->CardState |=
 +                              (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
 +                      status->CardState |=
 +                              (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
 +                      status->CardState |=
 +                              (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
 +              } else {
 +                      /* No PRR?  Then assume we're always ready */
 +                      status->CardState |= CS_EVENT_READY_CHANGE;
 +              }
 +              if (c->CardValues & PRESENT_EXT_STATUS) {
 +                      pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
 +                      status->CardState |=
 +                              (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
 +              }
 +              return CS_SUCCESS;
 +      }
 +      status->CardState |=
 +              (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
 +      status->CardState |=
 +              (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
 +      status->CardState |=
 +              (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
 +      status->CardState |=
 +              (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
 +      return CS_SUCCESS;
 +} /* pccard_get_status */
 +
  /*======================================================================
  
      These manage a ring buffer of events pending for one user process
@@@ -545,20 -398,27 +546,27 @@@ static int ds_open(struct inode *inode
      struct pcmcia_socket *s;
      user_info_t *user;
      static int warning_printed = 0;
+     int ret = 0;
  
      ds_dbg(0, "ds_open(socket %d)\n", i);
  
+     lock_kernel();
      s = pcmcia_get_socket_by_nr(i);
-     if (!s)
-           return -ENODEV;
+     if (!s) {
+           ret = -ENODEV;
+           goto out;
+     }
      s = pcmcia_get_socket(s);
-     if (!s)
-           return -ENODEV;
+     if (!s) {
+           ret = -ENODEV;
+           goto out;
+     }
  
      if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
            if (s->pcmcia_state.busy) {
                    pcmcia_put_socket(s);
-                   return -EBUSY;
+                   ret = -EBUSY;
+                   goto out;
            }
        else
            s->pcmcia_state.busy = 1;
      user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
      if (!user) {
            pcmcia_put_socket(s);
-           return -ENOMEM;
+           ret = -ENOMEM;
+           goto out;
      }
      user->event_tail = user->event_head = 0;
      user->next = s->user;
  
      if (s->pcmcia_state.present)
        queue_event(user, CS_EVENT_CARD_INSERTION);
-     return 0;
+ out:
+     unlock_kernel();
+     return ret;
  } /* ds_open */
  
  /*====================================================================*/
@@@ -694,6 -557,8 +705,6 @@@ static u_int ds_poll(struct file *file
  
  /*====================================================================*/
  
 -extern int pcmcia_adjust_resource_info(adjust_t *adj);
 -
  static int ds_ioctl(struct inode * inode, struct file * file,
                    u_int cmd, u_long arg)
  {
        mutex_lock(&s->skt_mutex);
        pcmcia_validate_mem(s);
        mutex_unlock(&s->skt_mutex);
 -      ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
 +      ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo.Chains);
        break;
      case DS_SUSPEND_CARD:
        ret = pcmcia_suspend_card(s);
@@@ -14,6 -14,7 +14,7 @@@
  #include <linux/interrupt.h>
  #include <linux/list.h>
  #include <linux/types.h>
+ #include <linux/smp_lock.h>
  
  #include <asm/ccwdev.h>
  #include <asm/cio.h>
@@@ -216,17 -217,17 +217,17 @@@ static in
  fs3270_irq(struct fs3270 *fp, struct raw3270_request *rq, struct irb *irb)
  {
        /* Handle ATTN. Set indication and wake waiters for attention. */
 -      if (irb->scsw.dstat & DEV_STAT_ATTENTION) {
 +      if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
                fp->attention = 1;
                wake_up(&fp->wait);
        }
  
        if (rq) {
 -              if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)
 +              if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)
                        rq->rc = -EIO;
                else
                        /* Normal end. Copy residual count. */
 -                      rq->rescnt = irb->scsw.count;
 +                      rq->rescnt = irb->scsw.cmd.count;
        }
        return RAW3270_IO_DONE;
  }
@@@ -421,6 -422,7 +422,7 @@@ fs3270_open(struct inode *inode, struc
  
        if (imajor(filp->f_path.dentry->d_inode) != IBM_FS3270_MAJOR)
                return -ENODEV;
+       lock_kernel();
        minor = iminor(filp->f_path.dentry->d_inode);
        /* Check for minor 0 multiplexer. */
        if (minor == 0) {
                tty = get_current_tty();
                if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
                        mutex_unlock(&tty_mutex);
-                       return -ENODEV;
+                       rc = -ENODEV;
+                       goto out;
                }
                minor = tty->index + RAW3270_FIRSTMINOR;
                mutex_unlock(&tty_mutex);
        fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor);
        if (!IS_ERR(fp)) {
                raw3270_put_view(&fp->view);
-               return -EBUSY;
+               rc = -EBUSY;
+               goto out;
        }
        /* Allocate fullscreen view structure. */
        fp = fs3270_alloc_view();
-       if (IS_ERR(fp))
-               return PTR_ERR(fp);
+       if (IS_ERR(fp)) {
+               rc = PTR_ERR(fp);
+               goto out;
+       }
  
        init_waitqueue_head(&fp->wait);
        fp->fs_pid = get_pid(task_pid(current));
        rc = raw3270_add_view(&fp->view, &fs3270_fn, minor);
        if (rc) {
                fs3270_free_view(&fp->view);
-               return rc;
+               goto out;
        }
  
        /* Allocate idal-buffer. */
        if (IS_ERR(ib)) {
                raw3270_put_view(&fp->view);
                raw3270_del_view(&fp->view);
-               return PTR_ERR(fp);
+               rc = PTR_ERR(fp);
+               goto out;
        }
        fp->rdbuf = ib;
  
        if (rc) {
                raw3270_put_view(&fp->view);
                raw3270_del_view(&fp->view);
-               return rc;
+               goto out;
        }
        filp->private_data = fp;
+ out:
+       unlock_kernel();
        return 0;
  }
  
@@@ -512,8 -521,11 +521,8 @@@ fs3270_init(void
        int rc;
  
        rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops);
 -      if (rc) {
 -              printk(KERN_ERR "fs3270 can't get major number %d: errno %d\n",
 -                     IBM_FS3270_MAJOR, rc);
 +      if (rc)
                return rc;
 -      }
        return 0;
  }
  
@@@ -3,13 -3,15 +3,14 @@@
   *
   * Character device driver for reading z/VM *MONITOR service records.
   *
 - * Copyright 2004 IBM Corporation, IBM Deutschland Entwicklung GmbH.
 - *
 - * Author: Gerald Schaefer <geraldsc@de.ibm.com>
 + *   Copyright IBM Corp. 2004, 2008
 + *   Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
   */
  
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/init.h>
+ #include <linux/smp_lock.h>
  #include <linux/errno.h>
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/ctype.h>
  #include <linux/spinlock.h>
  #include <linux/interrupt.h>
 +#include <linux/poll.h>
 +#include <net/iucv/iucv.h>
  #include <asm/uaccess.h>
  #include <asm/ebcdic.h>
  #include <asm/extmem.h>
 -#include <linux/poll.h>
 -#include <net/iucv/iucv.h>
 -
  
  //#define MON_DEBUG                   /* Debug messages on/off */
  
@@@ -150,7 -153,10 +151,7 @@@ static int mon_check_mca(struct mon_ms
            (mon_mca_end(monmsg) > mon_dcss_end) ||
            (mon_mca_start(monmsg) < mon_dcss_start) ||
            ((mon_mca_type(monmsg, 1) == 0) && (mon_mca_type(monmsg, 2) == 0)))
 -      {
 -              P_DEBUG("READ, IGNORED INVALID MCA\n\n");
                return -EINVAL;
 -      }
        return 0;
  }
  
@@@ -159,6 -165,10 +160,6 @@@ static int mon_send_reply(struct mon_ms
  {
        int rc;
  
 -      P_DEBUG("read, REPLY: pathid = 0x%04X, msgid = 0x%08X, trgcls = "
 -              "0x%08X\n\n",
 -              monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class);
 -
        rc = iucv_message_reply(monpriv->path, &monmsg->msg,
                                IUCV_IPRMDATA, NULL, 0);
        atomic_dec(&monpriv->msglim_count);
@@@ -193,12 -203,15 +194,12 @@@ static struct mon_private *mon_alloc_me
        struct mon_private *monpriv;
  
        monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL);
 -      if (!monpriv) {
 -              P_ERROR("no memory for monpriv\n");
 +      if (!monpriv)
                return NULL;
 -      }
        for (i = 0; i < MON_MSGLIM; i++) {
                monpriv->msg_array[i] = kzalloc(sizeof(struct mon_msg),
                                                    GFP_KERNEL);
                if (!monpriv->msg_array[i]) {
 -                      P_ERROR("open, no memory for msg_array\n");
                        mon_free_mem(monpriv);
                        return NULL;
                }
        return monpriv;
  }
  
 -static inline void mon_read_debug(struct mon_msg *monmsg,
 -                                struct mon_private *monpriv)
 -{
 -#ifdef MON_DEBUG
 -      u8 msg_type[2], mca_type;
 -      unsigned long records_len;
 -
 -      records_len = mon_rec_end(monmsg) - mon_rec_start(monmsg) + 1;
 -
 -      memcpy(msg_type, &monmsg->msg.class, 2);
 -      EBCASC(msg_type, 2);
 -      mca_type = mon_mca_type(monmsg, 0);
 -      EBCASC(&mca_type, 1);
 -
 -      P_DEBUG("read, mon_read_index = %i, mon_write_index = %i\n",
 -              monpriv->read_index, monpriv->write_index);
 -      P_DEBUG("read, pathid = 0x%04X, msgid = 0x%08X, trgcls = 0x%08X\n",
 -              monpriv->path->pathid, monmsg->msg.id, monmsg->msg.class);
 -      P_DEBUG("read, msg_type = '%c%c', mca_type = '%c' / 0x%X / 0x%X\n",
 -              msg_type[0], msg_type[1], mca_type ? mca_type : 'X',
 -              mon_mca_type(monmsg, 1), mon_mca_type(monmsg, 2));
 -      P_DEBUG("read, MCA: start = 0x%lX, end = 0x%lX\n",
 -              mon_mca_start(monmsg), mon_mca_end(monmsg));
 -      P_DEBUG("read, REC: start = 0x%X, end = 0x%X, len = %lu\n\n",
 -              mon_rec_start(monmsg), mon_rec_end(monmsg), records_len);
 -      if (mon_mca_size(monmsg) > 12)
 -              P_DEBUG("READ, MORE THAN ONE MCA\n\n");
 -#endif
 -}
 -
  static inline void mon_next_mca(struct mon_msg *monmsg)
  {
        if (likely((mon_mca_size(monmsg) - monmsg->mca_offset) == 12))
                return;
 -      P_DEBUG("READ, NEXT MCA\n\n");
        monmsg->mca_offset += 12;
        monmsg->pos = 0;
  }
@@@ -226,6 -270,7 +227,6 @@@ static struct mon_msg *mon_next_message
                monmsg->msglim_reached = 0;
                monmsg->pos = 0;
                monmsg->mca_offset = 0;
 -              P_WARNING("read, message limit reached\n");
                monpriv->read_index = (monpriv->read_index + 1) %
                                      MON_MSGLIM;
                atomic_dec(&monpriv->read_ready);
@@@ -242,6 -287,10 +243,6 @@@ static void mon_iucv_path_complete(stru
  {
        struct mon_private *monpriv = path->private;
  
 -      P_DEBUG("IUCV connection completed\n");
 -      P_DEBUG("IUCV ACCEPT (from *MONITOR): Version = 0x%02X, Event = "
 -              "0x%02X, Sample = 0x%02X\n",
 -              ipuser[0], ipuser[1], ipuser[2]);
        atomic_set(&monpriv->iucv_connected, 1);
        wake_up(&mon_conn_wait_queue);
  }
@@@ -262,6 -311,7 +263,6 @@@ static void mon_iucv_message_pending(st
  {
        struct mon_private *monpriv = path->private;
  
 -      P_DEBUG("IUCV message pending\n");
        memcpy(&monpriv->msg_array[monpriv->write_index]->msg,
               msg, sizeof(*msg));
        if (atomic_inc_return(&monpriv->msglim_count) == MON_MSGLIM) {
@@@ -291,6 -341,7 +292,7 @@@ static int mon_open(struct inode *inode
        /*
         * only one user allowed
         */
+       lock_kernel();
        rc = -EBUSY;
        if (test_and_set_bit(MON_IN_USE, &mon_in_use))
                goto out;
                rc = -EIO;
                goto out_path;
        }
 -      P_INFO("open, established connection to *MONITOR service\n\n");
        filp->private_data = monpriv;
+       unlock_kernel();
        return nonseekable_open(inode, filp);
  
  out_path:
@@@ -336,6 -389,7 +339,7 @@@ out_priv
  out_use:
        clear_bit(MON_IN_USE, &mon_in_use);
  out:
+       unlock_kernel();
        return rc;
  }
  
@@@ -350,6 -404,8 +354,6 @@@ static int mon_close(struct inode *inod
        rc = iucv_path_sever(monpriv->path, user_data_sever);
        if (rc)
                P_ERROR("close, iucv_sever failed with rc = %i\n", rc);
 -      else
 -              P_INFO("close, terminated connection to *MONITOR service\n");
  
        atomic_set(&monpriv->iucv_severed, 0);
        atomic_set(&monpriv->iucv_connected, 0);
@@@ -390,8 -446,10 +394,8 @@@ static ssize_t mon_read(struct file *fi
                monmsg = monpriv->msg_array[monpriv->read_index];
        }
  
 -      if (!monmsg->pos) {
 +      if (!monmsg->pos)
                monmsg->pos = mon_mca_start(monmsg) + monmsg->mca_offset;
 -              mon_read_debug(monmsg, monpriv);
 -      }
        if (mon_check_mca(monmsg))
                goto reply;
  
@@@ -477,6 -535,7 +481,6 @@@ static int __init mon_init(void
                P_ERROR("failed to register with iucv driver\n");
                return rc;
        }
 -      P_INFO("open, registered with IUCV\n");
  
        rc = segment_type(mon_dcss_name);
        if (rc < 0) {
        dcss_mkname(mon_dcss_name, &user_data_connect[8]);
  
        rc = misc_register(&mon_dev);
 -      if (rc < 0 ) {
 -              P_ERROR("misc_register failed, rc = %i\n", rc);
 +      if (rc < 0 )
                goto out;
 -      }
 -      P_INFO("Loaded segment %s from %p to %p, size = %lu Byte\n",
 -              mon_dcss_name, (void *) mon_dcss_start, (void *) mon_dcss_end,
 -              mon_dcss_end - mon_dcss_start + 1);
        return 0;
  
  out:
diff --combined drivers/s390/char/vmcp.c
@@@ -16,6 -16,7 +16,7 @@@
  #include <linux/kernel.h>
  #include <linux/miscdevice.h>
  #include <linux/module.h>
+ #include <linux/smp_lock.h>
  #include <asm/cpcmd.h>
  #include <asm/debug.h>
  #include <asm/uaccess.h>
@@@ -39,11 -40,14 +40,14 @@@ static int vmcp_open(struct inode *inod
        session = kmalloc(sizeof(*session), GFP_KERNEL);
        if (!session)
                return -ENOMEM;
+       lock_kernel();
        session->bufsize = PAGE_SIZE;
        session->response = NULL;
        session->resp_size = 0;
        mutex_init(&session->mutex);
        file->private_data = session;
+       unlock_kernel();
        return nonseekable_open(inode, file);
  }
  
@@@ -61,24 -65,30 +65,24 @@@ static int vmcp_release(struct inode *i
  static ssize_t
  vmcp_read(struct file *file, char __user *buff, size_t count, loff_t *ppos)
  {
 -      size_t tocopy;
 +      ssize_t ret;
 +      size_t size;
        struct vmcp_session *session;
  
 -      session = (struct vmcp_session *)file->private_data;
 +      session = file->private_data;
        if (mutex_lock_interruptible(&session->mutex))
                return -ERESTARTSYS;
        if (!session->response) {
                mutex_unlock(&session->mutex);
                return 0;
        }
 -      if (*ppos > session->resp_size) {
 -              mutex_unlock(&session->mutex);
 -              return 0;
 -      }
 -      tocopy = min(session->resp_size - (size_t) (*ppos), count);
 -      tocopy = min(tocopy, session->bufsize - (size_t) (*ppos));
 +      size = min_t(size_t, session->resp_size, session->bufsize);
 +      ret = simple_read_from_buffer(buff, count, ppos,
 +                                      session->response, size);
  
 -      if (copy_to_user(buff, session->response + (*ppos), tocopy)) {
 -              mutex_unlock(&session->mutex);
 -              return -EFAULT;
 -      }
        mutex_unlock(&session->mutex);
 -      *ppos += tocopy;
 -      return tocopy;
 +
 +      return ret;
  }
  
  static ssize_t
@@@ -192,23 -202,27 +196,23 @@@ static int __init vmcp_init(void
                PRINT_WARN("z/VM CP interface is only available under z/VM\n");
                return -ENODEV;
        }
 +
        vmcp_debug = debug_register("vmcp", 1, 1, 240);
 -      if (!vmcp_debug) {
 -              PRINT_ERR("z/VM CP interface not loaded. Could not register "
 -                         "debug feature\n");
 +      if (!vmcp_debug)
                return -ENOMEM;
 -      }
 +
        ret = debug_register_view(vmcp_debug, &debug_hex_ascii_view);
        if (ret) {
 -              PRINT_ERR("z/VM CP interface not loaded. Could not register "
 -                        "debug feature view. Error code: %d\n", ret);
                debug_unregister(vmcp_debug);
                return ret;
        }
 +
        ret = misc_register(&vmcp_dev);
        if (ret) {
 -              PRINT_ERR("z/VM CP interface not loaded. Could not register "
 -                         "misc device. Error code: %d\n", ret);
                debug_unregister(vmcp_debug);
                return ret;
        }
 -      PRINT_INFO("z/VM CP interface loaded\n");
 +
        return 0;
  }
  
@@@ -216,6 -230,7 +220,6 @@@ static void __exit vmcp_exit(void
  {
        misc_deregister(&vmcp_dev);
        debug_unregister(vmcp_debug);
 -      PRINT_INFO("z/VM CP interface unloaded.\n");
  }
  
  module_init(vmcp_init);
@@@ -25,6 -25,7 +25,7 @@@
  #include <linux/kmod.h>
  #include <linux/cdev.h>
  #include <linux/device.h>
+ #include <linux/smp_lock.h>
  #include <linux/string.h>
  
  
@@@ -216,7 -217,9 +217,7 @@@ static int vmlogrdr_get_recording_class
        char *tail;
        int len,i;
  
 -      printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command);
        cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 -      printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response);
        len = strnlen(cp_response,sizeof(cp_response));
        // now the parsing
        tail=strnchr(cp_response,len,'=');
@@@ -266,7 -269,11 +267,7 @@@ static int vmlogrdr_recording(struct vm
                         logptr->recording_name,
                         qid_string);
  
 -              printk (KERN_DEBUG "vmlogrdr: recording command: %s\n",
 -                      cp_command);
                cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 -              printk (KERN_DEBUG "vmlogrdr: recording response: %s",
 -                      cp_response);
        }
  
        memset(cp_command, 0x00, sizeof(cp_command));
                onoff,
                qid_string);
  
 -      printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
        cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 -      printk (KERN_DEBUG "vmlogrdr: recording response: %s",
 -              cp_response);
        /* The recording command will usually answer with 'Command complete'
         * on success, but when the specific service was never connected
         * before then there might be an additional informational message
@@@ -310,9 -320,11 +311,11 @@@ static int vmlogrdr_open (struct inode 
                return -ENOSYS;
  
        /* Besure this device hasn't already been opened */
+       lock_kernel();
        spin_lock_bh(&logptr->priv_lock);
        if (logptr->dev_in_use) {
                spin_unlock_bh(&logptr->priv_lock);
+               unlock_kernel();
                return -EBUSY;
        }
        logptr->dev_in_use = 1;
                   || (logptr->iucv_path_severed));
        if (logptr->iucv_path_severed)
                goto out_record;
-       return nonseekable_open(inode, filp);
+       ret = nonseekable_open(inode, filp);
+       unlock_kernel();
+       return ret;
  
  out_record:
        if (logptr->autorecording)
@@@ -366,6 -380,7 +371,7 @@@ out_path
        logptr->path = NULL;
  out_dev:
        logptr->dev_in_use = 0;
+       unlock_kernel();
        return -EIO;
  }
  
@@@ -558,7 -573,10 +564,7 @@@ static ssize_t vmlogrdr_purge_store(str
                         "RECORDING %s PURGE ",
                         priv->recording_name);
  
 -      printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
        cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 -      printk (KERN_DEBUG "vmlogrdr: recording response: %s",
 -              cp_response);
  
        return count;
  }
@@@ -670,20 -688,28 +676,20 @@@ static int vmlogrdr_register_driver(voi
  
        /* Register with iucv driver */
        ret = iucv_register(&vmlogrdr_iucv_handler, 1);
 -      if (ret) {
 -              printk (KERN_ERR "vmlogrdr: failed to register with "
 -                      "iucv driver\n");
 +      if (ret)
                goto out;
 -      }
  
        ret = driver_register(&vmlogrdr_driver);
 -      if (ret) {
 -              printk(KERN_ERR "vmlogrdr: failed to register driver.\n");
 +      if (ret)
                goto out_iucv;
 -      }
  
        ret = driver_create_file(&vmlogrdr_driver,
                                 &driver_attr_recording_status);
 -      if (ret) {
 -              printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n");
 +      if (ret)
                goto out_driver;
 -      }
  
        vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr");
        if (IS_ERR(vmlogrdr_class)) {
 -              printk(KERN_ERR "vmlogrdr: failed to create class.\n");
                ret = PTR_ERR(vmlogrdr_class);
                vmlogrdr_class = NULL;
                goto out_attr;
@@@ -851,10 -877,12 +857,10 @@@ static int __init vmlogrdr_init(void
        rc = vmlogrdr_register_cdev(dev);
        if (rc)
                goto cleanup;
 -      printk (KERN_INFO "vmlogrdr: driver loaded\n");
        return 0;
  
  cleanup:
        vmlogrdr_cleanup();
 -      printk (KERN_ERR "vmlogrdr: driver not loaded.\n");
        return rc;
  }
  
  static void __exit vmlogrdr_exit(void)
  {
        vmlogrdr_cleanup();
 -      printk (KERN_INFO "vmlogrdr: driver unloaded\n");
        return;
  }
  
diff --combined drivers/s390/char/vmur.c
@@@ -9,6 -9,7 +9,7 @@@
   */
  
  #include <linux/cdev.h>
+ #include <linux/smp_lock.h>
  
  #include <asm/uaccess.h>
  #include <asm/cio.h>
@@@ -277,8 -278,7 +278,8 @@@ static void ur_int_handler(struct ccw_d
        struct urdev *urd;
  
        TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n",
 -            intparm, irb->scsw.cstat, irb->scsw.dstat, irb->scsw.count);
 +            intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
 +            irb->scsw.cmd.count);
  
        if (!intparm) {
                TRACE("ur_int_handler: unsolicited interrupt\n");
        /* On special conditions irb is an error pointer */
        if (IS_ERR(irb))
                urd->io_request_rc = PTR_ERR(irb);
 -      else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
 +      else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
                urd->io_request_rc = 0;
        else
                urd->io_request_rc = -EIO;
@@@ -669,7 -669,7 +670,7 @@@ static int ur_open(struct inode *inode
  
        if (accmode == O_RDWR)
                return -EACCES;
+       lock_kernel();
        /*
         * We treat the minor number as the devno of the ur device
         * to find in the driver tree.
        devno = MINOR(file->f_dentry->d_inode->i_rdev);
  
        urd = urdev_get_from_devno(devno);
-       if (!urd)
-               return -ENXIO;
+       if (!urd) {
+               rc = -ENXIO;
+               goto out;
+       }
  
        spin_lock(&urd->open_lock);
        while (urd->open_flag) {
                goto fail_urfile_free;
        urf->file_reclen = rc;
        file->private_data = urf;
+       unlock_kernel();
        return 0;
  
  fail_urfile_free:
@@@ -731,6 -734,8 +735,8 @@@ fail_unlock
        spin_unlock(&urd->open_lock);
  fail_put:
        urdev_put(urd);
+ out:
+       unlock_kernel();
        return rc;
  }
  
@@@ -13,6 -13,7 +13,7 @@@
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/watchdog.h>
+ #include <linux/smp_lock.h>
  
  #include <asm/ebcdic.h>
  #include <asm/io.h>
@@@ -92,15 -93,23 +93,15 @@@ static int vmwdt_keepalive(void
  
        func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init;
        ret = __diag288(func, vmwdt_interval, ebc_cmd, len);
 +      WARN_ON(ret != 0);
        kfree(ebc_cmd);
 -
 -      if (ret) {
 -              printk(KERN_WARNING "%s: problem setting interval %d, "
 -                      "cmd %s\n", __func__, vmwdt_interval,
 -                      vmwdt_cmd);
 -      }
        return ret;
  }
  
  static int vmwdt_disable(void)
  {
        int ret = __diag288(wdt_cancel, 0, "", 0);
 -      if (ret) {
 -              printk(KERN_WARNING "%s: problem disabling watchdog\n",
 -                      __func__);
 -      }
 +      WARN_ON(ret != 0);
        return ret;
  }
  
@@@ -113,19 -122,25 +114,23 @@@ static int __init vmwdt_probe(void
        static char __initdata ebc_begin[] = {
                194, 197, 199, 201, 213
        };
 -      if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0) {
 -              printk(KERN_INFO "z/VM watchdog not available\n");
 +      if (__diag288(wdt_init, 15, ebc_begin, sizeof(ebc_begin)) != 0)
                return -EINVAL;
 -      }
        return vmwdt_disable();
  }
  
  static int vmwdt_open(struct inode *i, struct file *f)
  {
        int ret;
-       if (test_and_set_bit(0, &vmwdt_is_open))
+       lock_kernel();
+       if (test_and_set_bit(0, &vmwdt_is_open)) {
+               unlock_kernel();
                return -EBUSY;
+       }
        ret = vmwdt_keepalive();
        if (ret)
                clear_bit(0, &vmwdt_is_open);
+       unlock_kernel();
        return ret ? ret : nonseekable_open(i, f);
  }
  
@@@ -34,6 -34,7 +34,7 @@@
  #include <linux/fs.h>
  #include <linux/proc_fs.h>
  #include <linux/compat.h>
+ #include <linux/smp_lock.h>
  #include <asm/atomic.h>
  #include <asm/uaccess.h>
  #include <linux/hw_random.h>
@@@ -300,7 -301,9 +301,9 @@@ static ssize_t zcrypt_write(struct fil
   */
  static int zcrypt_open(struct inode *inode, struct file *filp)
  {
+       lock_kernel();
        atomic_inc(&zcrypt_open_count);
+       unlock_kernel();
        return 0;
  }
  
@@@ -1068,8 -1071,10 +1071,8 @@@ static int zcrypt_status_write(struct f
  
  #define LBUFSIZE 1200UL
        lbuf = kmalloc(LBUFSIZE, GFP_KERNEL);
 -      if (!lbuf) {
 -              PRINTK("kmalloc failed!\n");
 +      if (!lbuf)
                return 0;
 -      }
  
        local_count = min(LBUFSIZE - 1, count);
        if (copy_from_user(lbuf, buffer, local_count) != 0) {
        lbuf[local_count] = '\0';
  
        ptr = strstr(lbuf, "Online devices");
 -      if (!ptr) {
 -              PRINTK("Unable to parse data (missing \"Online devices\")\n");
 +      if (!ptr)
                goto out;
 -      }
        ptr = strstr(ptr, "\n");
 -      if (!ptr) {
 -              PRINTK("Unable to parse data (missing newline "
 -                     "after \"Online devices\")\n");
 +      if (!ptr)
                goto out;
 -      }
        ptr++;
  
 -      if (strstr(ptr, "Waiting work element counts") == NULL) {
 -              PRINTK("Unable to parse data (missing "
 -                     "\"Waiting work element counts\")\n");
 +      if (strstr(ptr, "Waiting work element counts") == NULL)
                goto out;
 -      }
  
        for (j = 0; j < 64 && *ptr; ptr++) {
                /*
@@@ -1187,12 -1200,16 +1190,12 @@@ int __init zcrypt_api_init(void
  
        /* Register the request sprayer. */
        rc = misc_register(&zcrypt_misc_device);
 -      if (rc < 0) {
 -              PRINTKW(KERN_ERR "misc_register (minor %d) failed with %d\n",
 -                      zcrypt_misc_device.minor, rc);
 +      if (rc < 0)
                goto out;
 -      }
  
        /* Set up the proc file system */
        zcrypt_entry = create_proc_entry("driver/z90crypt", 0644, NULL);
        if (!zcrypt_entry) {
 -              PRINTK("Couldn't create z90crypt proc entry\n");
                rc = -ENOMEM;
                goto out_misc;
        }
diff --combined drivers/scsi/sg.c
@@@ -49,6 -49,7 +49,7 @@@ static int sg_version_num = 30534;    /* 
  #include <linux/delay.h>
  #include <linux/scatterlist.h>
  #include <linux/blktrace_api.h>
+ #include <linux/smp_lock.h>
  
  #include "scsi.h"
  #include <scsi/scsi_dbg.h>
@@@ -182,9 -183,8 +183,9 @@@ static int sg_build_sgat(Sg_scatter_hol
                         int tablesize);
  static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count,
                           Sg_request * srp);
 -static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
 -                          int blocking, int read_only, Sg_request ** o_srp);
 +static ssize_t sg_new_write(Sg_fd *sfp, struct file *file,
 +                      const char __user *buf, size_t count, int blocking,
 +                      int read_only, Sg_request **o_srp);
  static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
                           unsigned char *cmnd, int timeout, int blocking);
  static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
@@@ -205,6 -205,7 +206,6 @@@ static Sg_request *sg_get_rq_mark(Sg_f
  static Sg_request *sg_add_request(Sg_fd * sfp);
  static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
  static int sg_res_in_use(Sg_fd * sfp);
 -static int sg_allow_access(unsigned char opcode, char dev_type);
  static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
  static Sg_device *sg_get_dev(int dev);
  #ifdef CONFIG_SCSI_PROC_FS
@@@ -227,19 -228,26 +228,26 @@@ sg_open(struct inode *inode, struct fil
        int res;
        int retval;
  
+       lock_kernel();
        nonseekable_open(inode, filp);
        SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
        sdp = sg_get_dev(dev);
-       if ((!sdp) || (!sdp->device))
+       if ((!sdp) || (!sdp->device)) {
+               unlock_kernel();
                return -ENXIO;
-       if (sdp->detached)
+       }
+       if (sdp->detached) {
+               unlock_kernel();
                return -ENODEV;
+       }
  
        /* This driver's module count bumped by fops_get in <linux/fs.h> */
        /* Prevent the device driver from vanishing while we sleep */
        retval = scsi_device_get(sdp->device);
-       if (retval)
+       if (retval) {
+               unlock_kernel();
                return retval;
+       }
  
        if (!((flags & O_NONBLOCK) ||
              scsi_block_when_processing_errors(sdp->device))) {
                retval = -ENOMEM;
                goto error_out;
        }
+       unlock_kernel();
        return 0;
  
        error_out:
        scsi_device_put(sdp->device);
+       unlock_kernel();
        return retval;
  }
  
@@@ -544,7 -554,7 +554,7 @@@ sg_write(struct file *filp, const char 
                return -EFAULT;
        blocking = !(filp->f_flags & O_NONBLOCK);
        if (old_hdr.reply_len < 0)
 -              return sg_new_write(sfp, buf, count, blocking, 0, NULL);
 +              return sg_new_write(sfp, filp, buf, count, blocking, 0, NULL);
        if (count < (SZ_SG_HEADER + 6))
                return -EIO;    /* The minimum scsi command length is 6 bytes. */
  
  }
  
  static ssize_t
 -sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
 -           int blocking, int read_only, Sg_request ** o_srp)
 +sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
 +               size_t count, int blocking, int read_only,
 +               Sg_request **o_srp)
  {
        int k;
        Sg_request *srp;
                sg_remove_request(sfp, srp);
                return -EFAULT;
        }
 -      if (read_only &&
 -          (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) {
 +      if (read_only && !blk_verify_command(file, cmnd)) {
                sg_remove_request(sfp, srp);
                return -EPERM;
        }
@@@ -799,7 -809,7 +809,7 @@@ sg_ioctl(struct inode *inode, struct fi
                        if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
                                return -EFAULT;
                        result =
 -                          sg_new_write(sfp, p, SZ_SG_IO_HDR,
 +                          sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
                                         blocking, read_only, &srp);
                        if (result < 0)
                                return result;
  
                        if (copy_from_user(&opcode, siocp->data, 1))
                                return -EFAULT;
 -                      if (!sg_allow_access(opcode, sdp->device->type))
 +                      if (!blk_verify_command(filp, &opcode))
                                return -EPERM;
                }
                return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p);
@@@ -2502,6 -2512,30 +2512,6 @@@ sg_page_free(struct page *page, int siz
        __free_pages(page, order);
  }
  
 -#ifndef MAINTENANCE_IN_CMD
 -#define MAINTENANCE_IN_CMD 0xa3
 -#endif
 -
 -static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE,
 -      INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
 -      READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS,
 -      SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD
 -};
 -
 -static int
 -sg_allow_access(unsigned char opcode, char dev_type)
 -{
 -      int k;
 -
 -      if (TYPE_SCANNER == dev_type)   /* TYPE_ROM maybe burner */
 -              return 1;
 -      for (k = 0; k < sizeof (allow_ops); ++k) {
 -              if (opcode == allow_ops[k])
 -                      return 1;
 -      }
 -      return 0;
 -}
 -
  #ifdef CONFIG_SCSI_PROC_FS
  static int
  sg_idr_max_id(int id, void *p, void *data)
diff --combined sound/core/sound.c
@@@ -21,6 -21,7 +21,7 @@@
  
  #include <linux/init.h>
  #include <linux/slab.h>
+ #include <linux/smp_lock.h>
  #include <linux/time.h>
  #include <linux/device.h>
  #include <linux/moduleparam.h>
@@@ -60,14 -61,14 +61,14 @@@ EXPORT_SYMBOL(snd_ecards_limit)
  static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
  static DEFINE_MUTEX(sound_mutex);
  
 -#ifdef CONFIG_KMOD
 +#ifdef CONFIG_MODULES
  
  /**
   * snd_request_card - try to load the card module
   * @card: the card number
   *
   * Tries to load the module "snd-card-X" for the given card number
 - * via KMOD.  Returns immediately if already loaded.
 + * via request_module.  Returns immediately if already loaded.
   */
  void snd_request_card(int card)
  {
@@@ -92,7 -93,7 +93,7 @@@ static void snd_request_other(int minor
        request_module(str);
  }
  
 -#endif                                /* request_module support */
 +#endif        /* modular kernel */
  
  /**
   * snd_lookup_minor_data - get user data of a registered device
@@@ -121,7 -122,7 +122,7 @@@ void *snd_lookup_minor_data(unsigned in
  
  EXPORT_SYMBOL(snd_lookup_minor_data);
  
- static int snd_open(struct inode *inode, struct file *file)
+ static int __snd_open(struct inode *inode, struct file *file)
  {
        unsigned int minor = iminor(inode);
        struct snd_minor *mptr = NULL;
                return -ENODEV;
        mptr = snd_minors[minor];
        if (mptr == NULL) {
 -#ifdef CONFIG_KMOD
 +#ifdef CONFIG_MODULES
                int dev = SNDRV_MINOR_DEVICE(minor);
                if (dev == SNDRV_MINOR_CONTROL) {
                        /* /dev/aloadC? */
        return err;
  }
  
+ /* BKL pushdown: nasty #ifdef avoidance wrapper */
+ static int snd_open(struct inode *inode, struct file *file)
+ {
+       int ret;
+       lock_kernel();
+       ret = __snd_open(inode, file);
+       unlock_kernel();
+       return ret;
+ }
  static const struct file_operations snd_fops =
  {
        .owner =        THIS_MODULE,