diff options
Diffstat (limited to 'drivers/char')
34 files changed, 412 insertions, 605 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 08a6f50ae79..6aad99ec4e0 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -323,7 +323,7 @@ config SPECIALIX config SX tristate "Specialix SX (and SI) card support" - depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) + depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN help This is a driver for the SX and SI multiport serial cards. Please read the file <file:Documentation/serial/sx.txt> for details. @@ -334,7 +334,7 @@ config SX config RIO tristate "Specialix RIO system support" - depends on SERIAL_NONSTANDARD + depends on SERIAL_NONSTANDARD && BROKEN help This is a driver for the Specialix RIO, a smart serial card which drives an outboard box that can support up to 128 ports. Product @@ -395,7 +395,7 @@ config NOZOMI config A2232 tristate "Commodore A2232 serial support (EXPERIMENTAL)" - depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP + depends on EXPERIMENTAL && ZORRO && BROKEN ---help--- This option supports the 2232 7-port serial card shipped with the Amiga 2000 and other Zorro-bus machines, dating from 1989. At diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index ccb1fa89de2..2fb3a480f6b 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig @@ -56,9 +56,8 @@ config AGP_AMD X on AMD Irongate, 761, and 762 chipsets. config AGP_AMD64 - tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU + tristate "AMD Opteron/Athlon64 on-CPU GART support" depends on AGP && X86 - default y if GART_IOMMU help This option gives you AGP support for the GLX component of X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index a96f3197e60..43412c03969 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c @@ -676,25 +676,25 @@ static int agp_open(struct inode *inode, struct file *file) int minor = iminor(inode); struct agp_file_private *priv; struct agp_client *client; - int rc = -ENXIO; - - lock_kernel(); - mutex_lock(&(agp_fe.agp_mutex)); if (minor != AGPGART_MINOR) - goto err_out; + return -ENXIO; + + mutex_lock(&(agp_fe.agp_mutex)); priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL); - if (priv == NULL) - goto err_out_nomem; + if (priv == NULL) { + mutex_unlock(&(agp_fe.agp_mutex)); + return -ENOMEM; + } set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags); priv->my_pid = current->pid; - if (capable(CAP_SYS_RAWIO)) { + if (capable(CAP_SYS_RAWIO)) /* Root priv, can be controller */ set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags); - } + client = agp_find_client_by_pid(current->pid); if (client != NULL) { @@ -704,16 +704,10 @@ static int agp_open(struct inode *inode, struct file *file) file->private_data = (void *) priv; agp_insert_file_private(priv); DBG("private=%p, client=%p", priv, client); - mutex_unlock(&(agp_fe.agp_mutex)); - unlock_kernel(); - return 0; -err_out_nomem: - rc = -ENOMEM; -err_out: mutex_unlock(&(agp_fe.agp_mutex)); - unlock_kernel(); - return rc; + + return 0; } diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 4068467ce7b..3cb56a049e2 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -62,6 +62,7 @@ #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 +#define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB 0x006a #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 /* cover 915 and 945 variants */ @@ -96,7 +97,8 @@ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB) extern int agp_memory_reserved; @@ -1161,12 +1163,6 @@ static int intel_i915_configure(void) intel_i9xx_setup_flush(); -#ifdef USE_PCI_DMA_API - if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) - dev_err(&intel_private.pcidev->dev, - "set gfx device dma mask 36bit failed!\n"); -#endif - return 0; } @@ -1364,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: + case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB: *gtt_offset = *gtt_size = MB(2); break; default: @@ -2365,6 +2362,8 @@ static const struct intel_driver_description { "IGDNG/M", NULL, &intel_i965_driver }, { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, "IGDNG/MA", NULL, &intel_i965_driver }, + { PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, + "IGDNG/MC2", NULL, &intel_i965_driver }, { 0, 0, 0, NULL, NULL, NULL } }; @@ -2456,6 +2455,11 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, &bridge->mode); } + if (bridge->driver->mask_memory == intel_i965_mask_memory) + if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) + dev_err(&intel_private.pcidev->dev, + "set gfx device dma mask 36bit failed!\n"); + pci_set_drvdata(pdev, bridge); return agp_add_bridge(bridge); } @@ -2561,6 +2565,7 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), + ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB), { } }; diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index 04ba906b488..4d830dc482e 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c @@ -17,7 +17,7 @@ #include <linux/cdev.h> #include <linux/ioport.h> #include <linux/pci.h> -#include <linux/smp_lock.h> + #include <asm/uaccess.h> #include <asm/io.h> @@ -158,7 +158,6 @@ static int cs5535_gpio_open(struct inode *inode, struct file *file) { u32 m = iminor(inode); - cycle_kernel_lock(); /* the mask says which pins are usable by this driver */ if ((mask & (1 << m)) == 0) return -EINVAL; diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c index 34d15d54823..26a47dc88f6 100644 --- a/drivers/char/efirtc.c +++ b/drivers/char/efirtc.c @@ -27,8 +27,6 @@ * - Add module support */ - -#include <linux/smp_lock.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/miscdevice.h> @@ -174,13 +172,12 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd, return -EINVAL; case RTC_RD_TIME: - lock_kernel(); spin_lock_irqsave(&efi_rtc_lock, flags); status = efi.get_time(&eft, &cap); spin_unlock_irqrestore(&efi_rtc_lock,flags); - unlock_kernel(); + if (status != EFI_SUCCESS) { /* should never happen */ printk(KERN_ERR "efitime: can't read time\n"); @@ -202,13 +199,11 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd, convert_to_efi_time(&wtime, &eft); - lock_kernel(); spin_lock_irqsave(&efi_rtc_lock, flags); status = efi.set_time(&eft); spin_unlock_irqrestore(&efi_rtc_lock,flags); - unlock_kernel(); return status == EFI_SUCCESS ? 0 : -EINVAL; @@ -224,7 +219,6 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd, convert_to_efi_time(&wtime, &eft); - lock_kernel(); spin_lock_irqsave(&efi_rtc_lock, flags); /* * XXX Fixme: @@ -235,19 +229,16 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd, status = efi.set_wakeup_time((efi_bool_t)enabled, &eft); spin_unlock_irqrestore(&efi_rtc_lock,flags); - unlock_kernel(); return status == EFI_SUCCESS ? 0 : -EINVAL; case RTC_WKALM_RD: - lock_kernel(); spin_lock_irqsave(&efi_rtc_lock, flags); status = efi.get_wakeup_time((efi_bool_t *)&enabled, (efi_bool_t *)&pending, &eft); spin_unlock_irqrestore(&efi_rtc_lock,flags); - unlock_kernel(); if (status != EFI_SUCCESS) return -EINVAL; @@ -277,7 +268,6 @@ static int efi_rtc_open(struct inode *inode, struct file *file) * We do accept multiple open files at the same time as we * synchronize on the per call operation. */ - cycle_kernel_lock(); return 0; } diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index ef31738c2cb..fda4181b5e6 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c @@ -19,7 +19,6 @@ #include <linux/miscdevice.h> #include <linux/fcntl.h> #include <linux/init.h> -#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/nvram.h> #ifdef CONFIG_PPC_PMAC @@ -32,7 +31,6 @@ static ssize_t nvram_len; static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) { - lock_kernel(); switch (origin) { case 1: offset += file->f_pos; @@ -41,12 +39,11 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) offset += nvram_len; break; } - if (offset < 0) { - unlock_kernel(); + if (offset < 0) return -EINVAL; - } + file->f_pos = offset; - unlock_kernel(); + return file->f_pos; } diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 70a770ac013..e481c5938ba 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -675,36 +675,33 @@ static int hpet_is_known(struct hpet_data *hdp) static ctl_table hpet_table[] = { { - .ctl_name = CTL_UNNUMBERED, .procname = "max-user-freq", .data = &hpet_max_freq, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec, + .proc_handler = proc_dointvec, }, - {.ctl_name = 0} + {} }; static ctl_table hpet_root[] = { { - .ctl_name = CTL_UNNUMBERED, .procname = "hpet", .maxlen = 0, .mode = 0555, .child = hpet_table, }, - {.ctl_name = 0} + {} }; static ctl_table dev_root[] = { { - .ctl_name = CTL_DEV, .procname = "dev", .maxlen = 0, .mode = 0555, .child = hpet_root, }, - {.ctl_name = 0} + {} }; static struct ctl_table_header *sysctl_header; diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index eba999f8598..a6ee32b599a 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c @@ -55,7 +55,7 @@ static inline void notify_daemon(void) notify_remote_via_evtchn(xen_start_info->console.domU.evtchn); } -static int write_console(uint32_t vtermno, const char *data, int len) +static int __write_console(const char *data, int len) { struct xencons_interface *intf = xencons_interface(); XENCONS_RING_IDX cons, prod; @@ -76,6 +76,29 @@ static int write_console(uint32_t vtermno, const char *data, int len) return sent; } +static int write_console(uint32_t vtermno, const char *data, int len) +{ + int ret = len; + + /* + * Make sure the whole buffer is emitted, polling if + * necessary. We don't ever want to rely on the hvc daemon + * because the most interesting console output is when the + * kernel is crippled. + */ + while (len) { + int sent = __write_console(data, len); + + data += sent; + len -= sent; + + if (unlikely(len)) + HYPERVISOR_sched_op(SCHEDOP_yield, NULL); + } + + return ret; +} + static int read_console(uint32_t vtermno, char *buf, int len) { struct xencons_interface *intf = xencons_interface(); diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 1573aebd54b..e989f67bb61 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -52,7 +52,9 @@ static struct hwrng *current_rng; static LIST_HEAD(rng_list); static DEFINE_MUTEX(rng_mutex); - +static int data_avail; +static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES] + __cacheline_aligned; static inline int hwrng_init(struct hwrng *rng) { @@ -67,19 +69,6 @@ static inline void hwrng_cleanup(struct hwrng *rng) rng->cleanup(rng); } -static inline int hwrng_data_present(struct hwrng *rng, int wait) -{ - if (!rng->data_present) - return 1; - return rng->data_present(rng, wait); -} - -static inline int hwrng_data_read(struct hwrng *rng, u32 *data) -{ - return rng->data_read(rng, data); -} - - static int rng_dev_open(struct inode *inode, struct file *filp) { /* enforce read-only access to this chrdev */ @@ -87,58 +76,90 @@ static int rng_dev_open(struct inode *inode, struct file *filp) return -EINVAL; if (filp->f_mode & FMODE_WRITE) return -EINVAL; - cycle_kernel_lock(); + return 0; +} + +static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size, + int wait) { + int present; + + if (rng->read) + return rng->read(rng, (void *)buffer, size, wait); + + if (rng->data_present) + present = rng->data_present(rng, wait); + else + present = 1; + + if (present) + return rng->data_read(rng, (u32 *)buffer); + return 0; } static ssize_t rng_dev_read(struct file *filp, char __user *buf, size_t size, loff_t *offp) { - u32 data; ssize_t ret = 0; int err = 0; - int bytes_read; + int bytes_read, len; while (size) { - err = -ERESTARTSYS; - if (mutex_lock_interruptible(&rng_mutex)) + if (mutex_lock_interruptible(&rng_mutex)) { + err = -ERESTARTSYS; goto out; + } + if (!current_rng) { - mutex_unlock(&rng_mutex); err = -ENODEV; - goto out; + goto out_unlock; } - bytes_read = 0; - if (hwrng_data_present(current_rng, - !(filp->f_flags & O_NONBLOCK))) - bytes_read = hwrng_data_read(current_rng, &data); - mutex_unlock(&rng_mutex); - - err = -EAGAIN; - if (!bytes_read && (filp->f_flags & O_NONBLOCK)) - goto out; - if (bytes_read < 0) { - err = bytes_read; - goto out; + if (!data_avail) { + bytes_read = rng_get_data(current_rng, rng_buffer, + sizeof(rng_buffer), + !(filp->f_flags & O_NONBLOCK)); + if (bytes_read < 0) { + err = bytes_read; + goto out_unlock; + } + data_avail = bytes_read; } - err = -EFAULT; - while (bytes_read && size) { - if (put_user((u8)data, buf++)) - goto out; - size--; - ret++; - bytes_read--; - data >>= 8; + if (!data_avail) { + if (filp->f_flags & O_NONBLOCK) { + err = -EAGAIN; + goto out_unlock; + } + } else { + len = data_avail; + if (len > size) + len = size; + + data_avail -= len; + + if (copy_to_user(buf + ret, rng_buffer + data_avail, + len)) { + err = -EFAULT; + goto out_unlock; + } + + size -= len; + ret += len; } + mutex_unlock(&rng_mutex); + if (need_resched()) schedule_timeout_interruptible(1); - err = -ERESTARTSYS; - if (signal_pending(current)) + + if (signal_pending(current)) { + err = -ERESTARTSYS; goto out; + } } +out_unlock: + mutex_unlock(&rng_mutex); out: return ret ? : err; } @@ -280,7 +301,7 @@ int hwrng_register(struct hwrng *rng) struct hwrng *old_rng, *tmp; if (rng->name == NULL || - rng->data_read == NULL) + (rng->data_read == NULL && rng->read == NULL)) goto out; mutex_lock(&rng_mutex); diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 962968f05b9..bdaef8e9402 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -16,86 +16,72 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + #include <linux/err.h> #include <linux/hw_random.h> #include <linux/scatterlist.h> #include <linux/spinlock.h> #include <linux/virtio.h> -#include <linux/virtio_ids.h> #include <linux/virtio_rng.h> -/* The host will fill any buffer we give it with sweet, sweet randomness. We - * give it 64 bytes at a time, and the hwrng framework takes it 4 bytes at a - * time. */ -#define RANDOM_DATA_SIZE 64 - static struct virtqueue *vq; -static u32 *random_data; -static unsigned int data_left; +static unsigned int data_avail; static DECLARE_COMPLETION(have_data); +static bool busy; static void random_recv_done(struct virtqueue *vq) { - unsigned int len; - /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ - if (!vq->vq_ops->get_buf(vq, &len)) + if (!vq->vq_ops->get_buf(vq, &data_avail)) return; - data_left += len; complete(&have_data); } -static void register_buffer(void) +/* The host will fill any buffer we give it with sweet, sweet randomness. */ +static void register_buffer(u8 *buf, size_t size) { struct scatterlist sg; - sg_init_one(&sg, random_data+data_left, RANDOM_DATA_SIZE-data_left); + sg_init_one(&sg, buf, size); + /* There should always be room for one buffer. */ - if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) < 0) + if (vq->vq_ops->add_buf(vq, &sg, 0, 1, buf) < 0) BUG(); + vq->vq_ops->kick(vq); } -/* At least we don't udelay() in a loop like some other drivers. */ -static int virtio_data_present(struct hwrng *rng, int wait) +static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) { - if (data_left >= sizeof(u32)) - return 1; -again: + if (!busy) { + busy = true; + init_completion(&have_data); + register_buffer(buf, size); + } + if (!wait) return 0; wait_for_completion(&have_data); - /* Not enough? Re-register. */ - if (unlikely(data_left < sizeof(u32))) { - register_buffer(); - goto again; - } + busy = false; - return 1; + return data_avail; } -/* virtio_data_present() must have succeeded before this is called. */ -static int virtio_data_read(struct hwrng *rng, u32 *data) +static void virtio_cleanup(struct hwrng *rng) { - BUG_ON(data_left < sizeof(u32)); - data_left -= sizeof(u32); - *data = random_data[data_left / 4]; - - if (data_left < sizeof(u32)) { - init_completion(&have_data); - register_buffer(); - } - return sizeof(*data); + if (busy) + wait_for_completion(&have_data); } + static struct hwrng virtio_hwrng = { - .name = "virtio", - .data_present = virtio_data_present, - .data_read = virtio_data_read, + .name = "virtio", + .cleanup = virtio_cleanup, + .read = virtio_read, }; static int virtrng_probe(struct virtio_device *vdev) @@ -113,11 +99,10 @@ static int virtrng_probe(struct virtio_device *vdev) return err; } - register_buffer(); return 0; } -static void virtrng_remove(struct virtio_device *vdev) +static void __devexit virtrng_remove(struct virtio_device *vdev) { vdev->config->reset(vdev); hwrng_unregister(&virtio_hwrng); @@ -139,21 +124,11 @@ static struct virtio_driver virtio_rng = { static int __init init(void) { - int err; - - random_data = kmalloc(RANDOM_DATA_SIZE, GFP_KERNEL); - if (!random_data) - return -ENOMEM; - - err = register_virtio_driver(&virtio_rng); - if (err) - kfree(random_data); - return err; + return register_virtio_driver(&virtio_rng); } static void __exit fini(void) { - kfree(random_data); unregister_virtio_driver(&virtio_rng); } module_init(init); diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 2e66b5f773d..0dec5da000e 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c @@ -660,26 +660,23 @@ static struct ipmi_smi_watcher smi_watcher = { #include <linux/sysctl.h> static ctl_table ipmi_table[] = { - { .ctl_name = DEV_IPMI_POWEROFF_POWERCYCLE, - .procname = "poweroff_powercycle", + { .procname = "poweroff_powercycle", .data = &poweroff_powercycle, .maxlen = sizeof(poweroff_powercycle), .mode = 0644, - .proc_handler = &proc_dointvec }, + .proc_handler = proc_dointvec }, { } }; static ctl_table ipmi_dir_table[] = { - { .ctl_name = DEV_IPMI, - .procname = "ipmi", + { .procname = "ipmi", .mode = 0555, .child = ipmi_table }, { } }; static ctl_table ipmi_root_table[] = { - { .ctl_name = CTL_DEV, - .procname = "dev", + { .procname = "dev", .mode = 0555, .child = ipmi_dir_table }, { } diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 737be953cc5..950837cf9e9 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) if (keycode >= NR_KEYS) if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) - keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); + keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1)); else return; else diff --git a/drivers/char/mem.c b/drivers/char/mem.c index a074fceb67d..ad82ec92ebd 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -26,7 +26,6 @@ #include <linux/bootmem.h> #include <linux/splice.h> #include <linux/pfn.h> -#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -892,29 +891,23 @@ static int memory_open(struct inode *inode, struct file *filp) { int minor; const struct memdev *dev; - int ret = -ENXIO; - - lock_kernel(); minor = iminor(inode); if (minor >= ARRAY_SIZE(devlist)) - goto out; + return -ENXIO; dev = &devlist[minor]; if (!dev->fops) - goto out; + return -ENXIO; filp->f_op = dev->fops; if (dev->dev_info) filp->f_mapping->backing_dev_info = dev->dev_info; if (dev->fops->open) - ret = dev->fops->open(inode, filp); - else - ret = 0; -out: - unlock_kernel(); - return ret; + return dev->fops->open(inode, filp); + + return 0; } static const struct file_operations memory_fops = { diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 07fa612a58d..96f1cd086dd 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -49,7 +49,6 @@ #include <linux/device.h> #include <linux/tty.h> #include <linux/kmod.h> -#include <linux/smp_lock.h> /* * Head entry for the doubly linked miscdevice list @@ -118,8 +117,7 @@ static int misc_open(struct inode * inode, struct file * file) struct miscdevice *c; int err = -ENODEV; const struct file_operations *old_fops, *new_fops = NULL; - - lock_kernel(); + mutex_lock(&misc_mtx); list_for_each_entry(c, &misc_list, list) { @@ -157,7 +155,6 @@ static int misc_open(struct inode * inode, struct file * file) fops_put(old_fops); fail: mutex_unlock(&misc_mtx); - unlock_kernel(); return err; } diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 88cee4099be..2100a8f7bd8 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -38,7 +38,6 @@ #define NVRAM_VERSION "1.3" #include <linux/module.h> -#include <linux/smp_lock.h> #include <linux/nvram.h> #define PC 1 @@ -214,7 +213,6 @@ void nvram_set_checksum(void) static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) { - lock_kernel(); switch (origin) { case 0: /* nothing to do */ @@ -226,7 +224,7 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) offset += NVRAM_BYTES; break; } - unlock_kernel(); + return (offset >= 0) ? (file->f_pos = offset) : -EINVAL; } diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 3f7da8cf3a8..8ecbcc174c1 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -20,7 +20,6 @@ #include <linux/mutex.h> #include <linux/nsc_gpio.h> #include <linux/platform_device.h> -#include <linux/smp_lock.h> #include <asm/uaccess.h> #define DEVNAME "pc8736x_gpio" @@ -223,7 +222,6 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file) unsigned m = iminor(inode); file->private_data = &pc8736x_gpio_ops; - cycle_kernel_lock(); dev_dbg(&pdev->dev, "open %d\n", m); if (m >= PC8736X_GPIO_CT) diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index c250a31efa5..2db4c0a29b0 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -23,8 +23,6 @@ * All rights reserved. Licensed under dual BSD/GPL license. */ -/* #define PCMCIA_DEBUG 6 */ - #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> @@ -47,18 +45,17 @@ /* #define ATR_CSUM */ -#ifdef PCMCIA_DEBUG -#define reader_to_dev(x) (&handle_to_dev(x->p_dev)) -static int pc_debug = PCMCIA_DEBUG; -module_param(pc_debug, int, 0600); -#define DEBUGP(n, rdr, x, args...) do { \ - if (pc_debug >= (n)) \ - dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ - __func__ , ## args); \ +#define reader_to_dev(x) (&x->p_dev->dev) + +/* n (debug level) is ignored */ +/* additional debug output may be enabled by re-compiling with + * CM4000_DEBUG set */ +/* #define CM4000_DEBUG */ +#define DEBUGP(n, rdr, x, args...) do { \ + dev_dbg(reader_to_dev(rdr), "%s:" x, \ + __func__ , ## args); \ } while (0) -#else -#define DEBUGP(n, rdr, x, args...) -#endif + static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte"; #define T_1SEC (HZ) @@ -174,14 +171,13 @@ static unsigned char fi_di_table[10][14] = { /* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9} }; -#ifndef PCMCIA_DEBUG +#ifndef CM4000_DEBUG #define xoutb outb #define xinb inb #else static inline void xoutb(unsigned char val, unsigned short port) { - if (pc_debug >= 7) - printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port); + pr_debug("outb(val=%.2x,port=%.4x)\n", val, port); outb(val, port); } static inline unsigned char xinb(unsigned short port) @@ -189,8 +185,7 @@ static inline unsigned char xinb(unsigned short port) unsigned char val; val = inb(port); - if (pc_debug >= 7) - printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port); + pr_debug("%.2x=inb(%.4x)\n", val, port); return val; } @@ -514,12 +509,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) for (i = 0; i < 4; i++) { xoutb(i, REG_BUF_ADDR(iobase)); xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */ -#ifdef PCMCIA_DEBUG - if (pc_debug >= 5) - printk("0x%.2x ", dev->pts[i]); +#ifdef CM4000_DEBUG + pr_debug("0x%.2x ", dev->pts[i]); } - if (pc_debug >= 5) - printk("\n"); + pr_debug("\n"); #else } #endif @@ -579,14 +572,13 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) pts_reply[i] = inb(REG_BUF_DATA(iobase)); } -#ifdef PCMCIA_DEBUG +#ifdef CM4000_DEBUG DEBUGP(2, dev, "PTSreply: "); for (i = 0; i < num_bytes_read; i++) { - if (pc_debug >= 5) - printk("0x%.2x ", pts_reply[i]); + pr_debug("0x%.2x ", pts_reply[i]); } - printk("\n"); -#endif /* PCMCIA_DEBUG */ + pr_debug("\n"); +#endif /* CM4000_DEBUG */ DEBUGP(5, dev, "Clear Tactive in Flags1\n"); xoutb(0x20, REG_FLAGS1(iobase)); @@ -655,7 +647,7 @@ static void terminate_monitor(struct cm4000_dev *dev) DEBUGP(5, dev, "Delete timer\n"); del_timer_sync(&dev->timer); -#ifdef PCMCIA_DEBUG +#ifdef CM4000_DEBUG dev->monitor_running = 0; #endif @@ -898,7 +890,7 @@ static void monitor_card(unsigned long p) DEBUGP(4, dev, "ATR checksum (0x%.2x, should " "be zero) failed\n", dev->atr_csum); } -#ifdef PCMCIA_DEBUG +#ifdef CM4000_DEBUG else if (test_bit(IS_BAD_LENGTH, &dev->flags)) { DEBUGP(4, dev, "ATR length error\n"); } else { @@ -1415,7 +1407,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int size; int rc; void __user *argp = (void __user *)arg; -#ifdef PCMCIA_DEBUG +#ifdef CM4000_DEBUG char *ioctl_names[CM_IOC_MAXNR + 1] = { [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS", [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR", @@ -1423,9 +1415,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS", [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL", }; -#endif DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode), iminor(inode), ioctl_names[_IOC_NR(cmd)]); +#endif lock_kernel(); rc = -ENODEV; @@ -1523,7 +1515,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } case CM_IOCARDOFF: -#ifdef PCMCIA_DEBUG +#ifdef CM4000_DEBUG DEBUGP(4, dev, "... in CM_IOCARDOFF\n"); if (dev->flags0 & 0x01) { DEBUGP(4, dev, " Card inserted\n"); @@ -1625,18 +1617,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; -#ifdef PCMCIA_DEBUG - case CM_IOSDBGLVL: /* set debug log level */ - { - int old_pc_debug = 0; - - old_pc_debug = pc_debug; - if (copy_from_user(&pc_debug, argp, sizeof(int))) - rc = -EFAULT; - else if (old_pc_debug != pc_debug) - DEBUGP(0, dev, "Changed debug log level " - "to %i\n", pc_debug); - } +#ifdef CM4000_DEBUG + case CM_IOSDBGLVL: + rc = -ENOTTY; break; #endif default: diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 4f0723b0797..a6a70e476be 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -17,8 +17,6 @@ * All rights reserved, Dual BSD/GPL Licensed. */ -/* #define PCMCIA_DEBUG 6 */ - #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> @@ -41,18 +39,16 @@ #include "cm4040_cs.h" -#ifdef PCMCIA_DEBUG -#define reader_to_dev(x) (&handle_to_dev(x->p_dev)) -static int pc_debug = PCMCIA_DEBUG; -module_param(pc_debug, int, 0600); -#define DEBUGP(n, rdr, x, args...) do { \ - if (pc_debug >= (n)) \ - dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ - __func__ , ##args); \ +#define reader_to_dev(x) (&x->p_dev->dev) + +/* n (debug level) is ignored */ +/* additional debug output may be enabled by re-compiling with + * CM4040_DEBUG set */ +/* #define CM4040_DEBUG */ +#define DEBUGP(n, rdr, x, args...) do { \ + dev_dbg(reader_to_dev(rdr), "%s:" x, \ + __func__ , ## args); \ } while (0) -#else -#define DEBUGP(n, rdr, x, args...) -#endif static char *version = "OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte"; @@ -90,14 +86,13 @@ struct reader_dev { static struct pcmcia_device *dev_table[CM_MAX_DEV]; -#ifndef PCMCIA_DEBUG +#ifndef CM4040_DEBUG #define xoutb outb #define xinb inb #else static inline void xoutb(unsigned char val, unsigned short port) { - if (pc_debug >= 7) - printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port); + pr_debug("outb(val=%.2x,port=%.4x)\n", val, port); outb(val, port); } @@ -106,8 +101,7 @@ static inline unsigned char xinb(unsigned short port) unsigned char val; val = inb(port); - if (pc_debug >= 7) - printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port); + pr_debug("%.2x=inb(%.4x)\n", val, port); return val; } #endif @@ -260,23 +254,22 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, return -EIO; } dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN); -#ifdef PCMCIA_DEBUG - if (pc_debug >= 6) - printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); +#ifdef CM4040_DEBUG + pr_debug("%lu:%2x ", i, dev->r_buf[i]); } - printk("\n"); + pr_debug("\n"); #else } #endif bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]); - DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read); + DEBUGP(6, dev, "BytesToRead=%zu\n", bytes_to_read); min_bytes_to_read = min(count, bytes_to_read + 5); min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE); - DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read); + DEBUGP(6, dev, "Min=%zu\n", min_bytes_to_read); for (i = 0; i < (min_bytes_to_read-5); i++) { rc = wait_for_bulk_in_ready(dev); @@ -288,11 +281,10 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, return -EIO; } dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN); -#ifdef PCMCIA_DEBUG - if (pc_debug >= 6) - printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); +#ifdef CM4040_DEBUG + pr_debug("%lu:%2x ", i, dev->r_buf[i]); } - printk("\n"); + pr_debug("\n"); #else } #endif @@ -547,7 +539,7 @@ static int cm4040_config_check(struct pcmcia_device *p_dev, p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; rc = pcmcia_request_io(p_dev, &p_dev->io); - dev_printk(KERN_INFO, &handle_to_dev(p_dev), + dev_printk(KERN_INFO, &p_dev->dev, "pcmcia_request_io returned 0x%x\n", rc); return rc; } @@ -569,7 +561,7 @@ static int reader_config(struct pcmcia_device *link, int devno) fail_rc = pcmcia_request_configuration(link, &link->conf); if (fail_rc != 0) { - dev_printk(KERN_INFO, &handle_to_dev(link), + dev_printk(KERN_INFO, &link->dev, "pcmcia_request_configuration failed 0x%x\n", fail_rc); goto cs_release; diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c index 4c1820cad71..99cffdab105 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.c +++ b/drivers/char/pcmcia/ipwireless/hardware.c @@ -1213,12 +1213,12 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, irqreturn_t ipwireless_interrupt(int irq, void *dev_id) { - struct ipw_hardware *hw = dev_id; + struct ipw_dev *ipw = dev_id; - if (hw->hw_version == HW_VERSION_1) - return ipwireless_handle_v1_interrupt(irq, hw); + if (ipw->hardware->hw_version == HW_VERSION_1) + return ipwireless_handle_v1_interrupt(irq, ipw->hardware); else - return ipwireless_handle_v2_v3_interrupt(irq, hw); + return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware); } static void flush_packets_to_hw(struct ipw_hardware *hw) diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 5216fce0c62..dff24dae148 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c @@ -65,10 +65,7 @@ static void signalled_reboot_work(struct work_struct *work_reboot) struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, work_reboot); struct pcmcia_device *link = ipw->link; - int ret = pcmcia_reset_card(link->socket); - - if (ret != 0) - cs_error(link, ResetCard, ret); + pcmcia_reset_card(link->socket); } static void signalled_reboot_callback(void *callback_data) @@ -79,208 +76,127 @@ static void signalled_reboot_callback(void *callback_data) schedule_work(&ipw->work_reboot); } -static int config_ipwireless(struct ipw_dev *ipw) +static int ipwireless_probe(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) { - struct pcmcia_device *link = ipw->link; - int ret; - tuple_t tuple; - unsigned short buf[64]; - cisparse_t parse; - unsigned short cor_value; + struct ipw_dev *ipw = priv_data; + struct resource *io_resource; memreq_t memreq_attr_memory; memreq_t memreq_common_memory; + int ret; - ipw->is_v2_card = 0; - - tuple.Attributes = 0; - tuple.TupleData = (cisdata_t *) buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - - tuple.DesiredTuple = RETURN_FIRST_TUPLE; - - ret = pcmcia_get_first_tuple(link, &tuple); - - while (ret == 0) { - ret = pcmcia_get_tuple_data(link, &tuple); - - if (ret != 0) { - cs_error(link, GetTupleData, ret); - goto exit0; - } - ret = pcmcia_get_next_tuple(link, &tuple); - } - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - - ret = pcmcia_get_first_tuple(link, &tuple); - - if (ret != 0) { - cs_error(link, GetFirstTuple, ret); - goto exit0; - } - - ret = pcmcia_get_tuple_data(link, &tuple); - - if (ret != 0) { - cs_error(link, GetTupleData, ret); - goto exit0; - } - - ret = pcmcia_parse_tuple(&tuple, &parse); - - if (ret != 0) { - cs_error(link, ParseTuple, ret); - goto exit0; - } - - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - link->io.BasePort1 = parse.cftable_entry.io.win[0].base; - link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; - link->io.IOAddrLines = 16; - - link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1; + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + p_dev->io.BasePort1 = cfg->io.win[0].base; + p_dev->io.NumPorts1 = cfg->io.win[0].len; + p_dev->io.IOAddrLines = 16; /* 0x40 causes it to generate level mode interrupts. */ /* 0x04 enables IREQ pin. */ - cor_value = parse.cftable_entry.index | 0x44; - link->conf.ConfigIndex = cor_value; + p_dev->conf.ConfigIndex = cfg->index | 0x44; + ret = pcmcia_request_io(p_dev, &p_dev->io); + if (ret) + return ret; - /* IRQ and I/O settings */ - tuple.DesiredTuple = CISTPL_CONFIG; + io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1, + IPWIRELESS_PCCARD_NAME); - ret = pcmcia_get_first_tuple(link, &tuple); + if (cfg->mem.nwin == 0) + return 0; - if (ret != 0) { - cs_error(link, GetFirstTuple, ret); - goto exit0; - } + ipw->request_common_memory.Attributes = + WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; + ipw->request_common_memory.Base = cfg->mem.win[0].host_addr; + ipw->request_common_memory.Size = cfg->mem.win[0].len; + if (ipw->request_common_memory.Size < 0x1000) + ipw->request_common_memory.Size = 0x1000; + ipw->request_common_memory.AccessSpeed = 0; - ret = pcmcia_get_tuple_data(link, &tuple); - - if (ret != 0) { - cs_error(link, GetTupleData, ret); - goto exit0; - } + ret = pcmcia_request_window(p_dev, &ipw->request_common_memory, + &ipw->handle_common_memory); - ret = pcmcia_parse_tuple(&tuple, &parse); + if (ret != 0) + goto exit1; - if (ret != 0) { - cs_error(link, GetTupleData, ret); - goto exit0; - } - link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.ConfigBase = parse.config.base; - link->conf.Present = parse.config.rmask[0]; - link->conf.IntType = INT_MEMORY_AND_IO; + memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr; + memreq_common_memory.Page = 0; - link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; - link->irq.Handler = ipwireless_interrupt; - link->irq.Instance = ipw->hardware; + ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory, + &memreq_common_memory); - ret = pcmcia_request_io(link, &link->io); + if (ret != 0) + goto exit2; - if (ret != 0) { - cs_error(link, RequestIO, ret); - goto exit0; - } + ipw->is_v2_card = cfg->mem.win[0].len == 0x100; - request_region(link->io.BasePort1, link->io.NumPorts1, + ipw->common_memory = ioremap(ipw->request_common_memory.Base, + ipw->request_common_memory.Size); + request_mem_region(ipw->request_common_memory.Base, + ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME); - /* memory settings */ - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - - ret = pcmcia_get_first_tuple(link, &tuple); - - if (ret != 0) { - cs_error(link, GetFirstTuple, ret); - goto exit1; - } - - ret = pcmcia_get_tuple_data(link, &tuple); + ipw->request_attr_memory.Attributes = + WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; + ipw->request_attr_memory.Base = 0; + ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ + ipw->request_attr_memory.AccessSpeed = 0; - if (ret != 0) { - cs_error(link, GetTupleData, ret); - goto exit1; - } - - ret = pcmcia_parse_tuple(&tuple, &parse); - - if (ret != 0) { - cs_error(link, ParseTuple, ret); - goto exit1; - } + ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory, + &ipw->handle_attr_memory); - if (parse.cftable_entry.mem.nwin > 0) { - ipw->request_common_memory.Attributes = - WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; - ipw->request_common_memory.Base = - parse.cftable_entry.mem.win[0].host_addr; - ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len; - if (ipw->request_common_memory.Size < 0x1000) - ipw->request_common_memory.Size = 0x1000; - ipw->request_common_memory.AccessSpeed = 0; - - ret = pcmcia_request_window(&link, &ipw->request_common_memory, - &ipw->handle_common_memory); + if (ret != 0) + goto exit2; - if (ret != 0) { - cs_error(link, RequestWindow, ret); - goto exit1; - } + memreq_attr_memory.CardOffset = 0; + memreq_attr_memory.Page = 0; - memreq_common_memory.CardOffset = - parse.cftable_entry.mem.win[0].card_addr; - memreq_common_memory.Page = 0; + ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory, + &memreq_attr_memory); - ret = pcmcia_map_mem_page(ipw->handle_common_memory, - &memreq_common_memory); + if (ret != 0) + goto exit3; - if (ret != 0) { - cs_error(link, MapMemPage, ret); - goto exit1; - } + ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, + ipw->request_attr_memory.Size); + request_mem_region(ipw->request_attr_memory.Base, + ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME); - ipw->is_v2_card = - parse.cftable_entry.mem.win[0].len == 0x100; + return 0; - ipw->common_memory = ioremap(ipw->request_common_memory.Base, +exit3: + pcmcia_release_window(p_dev, ipw->handle_attr_memory); +exit2: + if (ipw->common_memory) { + release_mem_region(ipw->request_common_memory.Base, ipw->request_common_memory.Size); - request_mem_region(ipw->request_common_memory.Base, - ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME); - - ipw->request_attr_memory.Attributes = - WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; - ipw->request_attr_memory.Base = 0; - ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ - ipw->request_attr_memory.AccessSpeed = 0; - - ret = pcmcia_request_window(&link, &ipw->request_attr_memory, - &ipw->handle_attr_memory); + iounmap(ipw->common_memory); + pcmcia_release_window(p_dev, ipw->handle_common_memory); + } else + pcmcia_release_window(p_dev, ipw->handle_common_memory); +exit1: + release_resource(io_resource); + pcmcia_disable_device(p_dev); + return -1; +} - if (ret != 0) { - cs_error(link, RequestWindow, ret); - goto exit2; - } +static int config_ipwireless(struct ipw_dev *ipw) +{ + struct pcmcia_device *link = ipw->link; + int ret = 0; - memreq_attr_memory.CardOffset = 0; - memreq_attr_memory.Page = 0; + ipw->is_v2_card = 0; - ret = pcmcia_map_mem_page(ipw->handle_attr_memory, - &memreq_attr_memory); + ret = pcmcia_loop_config(link, ipwireless_probe, ipw); + if (ret != 0) + return ret; - if (ret != 0) { - cs_error(link, MapMemPage, ret); - goto exit2; - } + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.IntType = INT_MEMORY_AND_IO; - ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, - ipw->request_attr_memory.Size); - request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size, - IPWIRELESS_PCCARD_NAME); - } + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; + link->irq.Handler = ipwireless_interrupt; INIT_WORK(&ipw->work_reboot, signalled_reboot_work); @@ -291,10 +207,8 @@ static int config_ipwireless(struct ipw_dev *ipw) ret = pcmcia_request_irq(link, &link->irq); - if (ret != 0) { - cs_error(link, RequestIRQ, ret); - goto exit3; - } + if (ret != 0) + goto exit; printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", ipw->is_v2_card ? "V2/V3" : "V1"); @@ -316,12 +230,12 @@ static int config_ipwireless(struct ipw_dev *ipw) ipw->network = ipwireless_network_create(ipw->hardware); if (!ipw->network) - goto exit3; + goto exit; ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network, ipw->nodes); if (!ipw->tty) - goto exit3; + goto exit; ipwireless_init_hardware_v2_v3(ipw->hardware); @@ -331,35 +245,27 @@ static int config_ipwireless(struct ipw_dev *ipw) */ ret = pcmcia_request_configuration(link, &link->conf); - if (ret != 0) { - cs_error(link, RequestConfiguration, ret); - goto exit4; - } + if (ret != 0) + goto exit; link->dev_node = &ipw->nodes[0]; return 0; -exit4: - pcmcia_disable_device(link); -exit3: +exit: if (ipw->attr_memory) { release_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size); iounmap(ipw->attr_memory); - pcmcia_release_window(ipw->handle_attr_memory); - pcmcia_disable_device(link); + pcmcia_release_window(link, ipw->handle_attr_memory); } -exit2: if (ipw->common_memory) { release_mem_region(ipw->request_common_memory.Base, ipw->request_common_memory.Size); iounmap(ipw->common_memory); - pcmcia_release_window(ipw->handle_common_memory); + pcmcia_release_window(link, ipw->handle_common_memory); } -exit1: pcmcia_disable_device(link); -exit0: return -1; } @@ -378,9 +284,9 @@ static void release_ipwireless(struct ipw_dev *ipw) iounmap(ipw->attr_memory); } if (ipw->common_memory) - pcmcia_release_window(ipw->handle_common_memory); + pcmcia_release_window(ipw->link, ipw->handle_common_memory); if (ipw->attr_memory) - pcmcia_release_window(ipw->handle_attr_memory); + pcmcia_release_window(ipw->link, ipw->handle_attr_memory); /* Break the link with Card Services */ pcmcia_disable_device(ipw->link); @@ -406,7 +312,6 @@ static int ipwireless_attach(struct pcmcia_device *link) ipw->link = link; link->priv = ipw; - link->irq.Instance = ipw; /* Link this device into our device list. */ link->dev_node = &ipw->nodes[0]; @@ -421,7 +326,6 @@ static int ipwireless_attach(struct pcmcia_device *link) ret = config_ipwireless(ipw); if (ret != 0) { - cs_error(link, RegisterClient, ret); ipwireless_detach(link); return ret; } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index caf6e4d1946..c31a0d913d3 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -554,7 +554,6 @@ static int mgslpc_probe(struct pcmcia_device *link) /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = NULL; link->conf.Attributes = 0; @@ -572,69 +571,51 @@ static int mgslpc_probe(struct pcmcia_device *link) /* Card has been inserted. */ -#define CS_CHECK(fn, ret) \ -do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) +static int mgslpc_ioprobe(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + if (cfg->io.nwin > 0) { + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + if (!(cfg->io.flags & CISTPL_IO_8BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; + if (!(cfg->io.flags & CISTPL_IO_16BIT)) + p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; + p_dev->io.BasePort1 = cfg->io.win[0].base; + p_dev->io.NumPorts1 = cfg->io.win[0].len; + return pcmcia_request_io(p_dev, &p_dev->io); + } + return -ENODEV; +} static int mgslpc_config(struct pcmcia_device *link) { MGSLPC_INFO *info = link->priv; - tuple_t tuple; - cisparse_t parse; - int last_fn, last_ret; - u_char buf[64]; - cistpl_cftable_entry_t dflt = { 0 }; - cistpl_cftable_entry_t *cfg; + int ret; if (debug_level >= DEBUG_LEVEL_INFO) printk("mgslpc_config(0x%p)\n", link); - tuple.Attributes = 0; - tuple.TupleData = buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - - /* get CIS configuration entry */ - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - - cfg = &(parse.cftable_entry); - CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); - CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); - - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; - if (cfg->index == 0) - goto cs_failed; - - link->conf.ConfigIndex = cfg->index; - link->conf.Attributes |= CONF_ENABLE_IRQ; - - /* IO window settings */ - link->io.NumPorts1 = 0; - if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { - cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; - link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; - if (!(io->flags & CISTPL_IO_8BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - if (!(io->flags & CISTPL_IO_16BIT)) - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - link->io.BasePort1 = io->win[0].base; - link->io.NumPorts1 = io->win[0].len; - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); - } + ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL); + if (ret != 0) + goto failed; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; link->conf.ConfigIndex = 8; link->conf.Present = PRESENT_OPTION; - link->irq.Attributes |= IRQ_HANDLE_PRESENT; link->irq.Handler = mgslpc_isr; - link->irq.Instance = info; - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + ret = pcmcia_request_irq(link, &link->irq); + if (ret) + goto failed; + ret = pcmcia_request_configuration(link, &link->conf); + if (ret) + goto failed; info->io_base = link->io.BasePort1; info->irq_level = link->irq.AssignedIRQ; @@ -654,8 +635,7 @@ static int mgslpc_config(struct pcmcia_device *link) printk("\n"); return 0; -cs_failed: - cs_error(link, last_fn, last_ret); +failed: mgslpc_release((u_long)link); return -ENODEV; } diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 62f282e6763..d86c0bc05c1 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -431,30 +431,25 @@ static struct cdev ptmx_cdev; static struct ctl_table pty_table[] = { { - .ctl_name = PTY_MAX, .procname = "max", .maxlen = sizeof(int), .mode = 0644, .data = &pty_limit, - .proc_handler = &proc_dointvec_minmax, - .strategy = &sysctl_intvec, + .proc_handler = proc_dointvec_minmax, .extra1 = &pty_limit_min, .extra2 = &pty_limit_max, }, { - .ctl_name = PTY_NR, .procname = "nr", .maxlen = sizeof(int), .mode = 0444, .data = &pty_count, - .proc_handler = &proc_dointvec, - }, { - .ctl_name = 0 - } + .proc_handler = proc_dointvec, + }, + {} }; static struct ctl_table pty_kern_table[] = { { - .ctl_name = KERN_PTY, .procname = "pty", .mode = 0555, .child = pty_table, @@ -464,7 +459,6 @@ static struct ctl_table pty_kern_table[] = { static struct ctl_table pty_root_table[] = { { - .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555, .child = pty_kern_table, diff --git a/drivers/char/random.c b/drivers/char/random.c index 04b505e5a5e..dcd08635cf1 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1257,94 +1257,54 @@ static int proc_do_uuid(ctl_table *table, int write, return proc_dostring(&fake_table, write, buffer, lenp, ppos); } -static int uuid_strategy(ctl_table *table, - void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen) -{ - unsigned char tmp_uuid[16], *uuid; - unsigned int len; - - if (!oldval || !oldlenp) - return 1; - - uuid = table->data; - if (!uuid) { - uuid = tmp_uuid; - uuid[8] = 0; - } - if (uuid[8] == 0) - generate_random_uuid(uuid); - - if (get_user(len, oldlenp)) - return -EFAULT; - if (len) { - if (len > 16) - len = 16; - if (copy_to_user(oldval, uuid, len) || - put_user(len, oldlenp)) - return -EFAULT; - } - return 1; -} - static int sysctl_poolsize = INPUT_POOL_WORDS * 32; ctl_table random_table[] = { { - .ctl_name = RANDOM_POOLSIZE, .procname = "poolsize", .data = &sysctl_poolsize, .maxlen = sizeof(int), .mode = 0444, - .proc_handler = &proc_dointvec, + .proc_handler = proc_dointvec, }, { - .ctl_name = RANDOM_ENTROPY_COUNT, .procname = "entropy_avail", .maxlen = sizeof(int), .mode = 0444, - .proc_handler = &proc_dointvec, + .proc_handler = proc_dointvec, .data = &input_pool.entropy_count, }, { - .ctl_name = RANDOM_READ_THRESH, .procname = "read_wakeup_threshold", .data = &random_read_wakeup_thresh, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .strategy = &sysctl_intvec, + .proc_handler = proc_dointvec_minmax, .extra1 = &min_read_thresh, .extra2 = &max_read_thresh, }, { - .ctl_name = RANDOM_WRITE_THRESH, .procname = "write_wakeup_threshold", .data = &random_write_wakeup_thresh, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .strategy = &sysctl_intvec, + .proc_handler = proc_dointvec_minmax, .extra1 = &min_write_thresh, .extra2 = &max_write_thresh, }, { - .ctl_name = RANDOM_BOOT_ID, .procname = "boot_id", .data = &sysctl_bootid, .maxlen = 16, .mode = 0444, - .proc_handler = &proc_do_uuid, - .strategy = &uuid_strategy, + .proc_handler = proc_do_uuid, }, { - .ctl_name = RANDOM_UUID, .procname = "uuid", .maxlen = 16, .mode = 0444, - .proc_handler = &proc_do_uuid, - .strategy = &uuid_strategy, + .proc_handler = proc_do_uuid, }, - { .ctl_name = 0 } + { } }; #endif /* CONFIG_SYSCTL */ diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index bc4ab3e5455..95acb8c880f 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -282,34 +282,31 @@ static irqreturn_t rtc_interrupt(int irq, void *dev_id) */ static ctl_table rtc_table[] = { { - .ctl_name = CTL_UNNUMBERED, .procname = "max-user-freq", .data = &rtc_max_user_freq, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec, + .proc_handler = proc_dointvec, }, - { .ctl_name = 0 } + { } }; static ctl_table rtc_root[] = { { - .ctl_name = CTL_UNNUMBERED, .procname = "rtc", .mode = 0555, .child = rtc_table, }, - { .ctl_name = 0 } + { } }; static ctl_table dev_root[] = { { - .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = rtc_root, }, - { .ctl_name = 0 } + { } }; static struct ctl_table_header *sysctl_header; diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 1d9100561c8..99e5272e3c5 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -12,7 +12,6 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -52,7 +51,6 @@ static int scx200_gpio_open(struct inode *inode, struct file *file) unsigned m = iminor(inode); file->private_data = &scx200_gpio_ops; - cycle_kernel_lock(); if (m >= MAX_PINS) return -EINVAL; return nonseekable_open(inode, file); diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index b3ec9b10e29..cad4eb65f13 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -21,7 +21,6 @@ #include <linux/fs.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/smp_lock.h> #include <asm/io.h> #include <asm/reboot.h> @@ -38,7 +37,7 @@ MODULE_PARM_DESC(major, "Major device number"); static void (*old_machine_restart)(char *command); static void __iomem *tb0219_base; -static spinlock_t tb0219_lock; +static DEFINE_SPINLOCK(tb0219_lock); #define tb0219_read(offset) readw(tb0219_base + (offset)) #define tb0219_write(offset, value) writew((value), tb0219_base + (offset)) @@ -237,7 +236,6 @@ static int tanbac_tb0219_open(struct inode *inode, struct file *file) { unsigned int minor; - cycle_kernel_lock(); minor = iminor(inode); switch (minor) { case 0: @@ -306,8 +304,6 @@ static int __devinit tb0219_probe(struct platform_device *dev) return retval; } - spin_lock_init(&tb0219_lock); - old_machine_restart = _machine_restart; _machine_restart = tb0219_restart; diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 47c2d276345..f06bb37defb 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -31,7 +31,7 @@ enum tpm_const { TPM_MINOR = 224, /* officially assigned */ - TPM_BUFSIZE = 2048, + TPM_BUFSIZE = 4096, TPM_NUM_DEVICES = 256, }; diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 0b73e4ec1ad..2405f17b29d 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -257,6 +257,10 @@ out: return size; } +static int itpm; +module_param(itpm, bool, 0444); +MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)"); + /* * If interrupts are used (signaled by an irq set in the vendor structure) * tpm.c can skip polling for the data to be available as the interrupt is @@ -293,7 +297,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &chip->vendor.int_queue); status = tpm_tis_status(chip); - if ((status & TPM_STS_DATA_EXPECT) == 0) { + if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { rc = -EIO; goto out_err; } @@ -467,6 +471,10 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, "1.2 TPM (device-id 0x%X, rev-id %d)\n", vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); + if (itpm) + dev_info(dev, "Intel iTPM workaround enabled\n"); + + /* Figure out the capabilities */ intfcaps = ioread32(chip->vendor.iobase + @@ -629,6 +637,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { {"", 0}, /* User Specified */ {"", 0} /* Terminator */ }; +MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) { diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index 3108991c5c8..66fa4e10d76 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c @@ -402,28 +402,26 @@ static void flush_to_ldisc(struct work_struct *work) container_of(work, struct tty_struct, buf.work.work); unsigned long flags; struct tty_ldisc *disc; - struct tty_buffer *tbuf, *head; - char *char_buf; - unsigned char *flag_buf; disc = tty_ldisc_ref(tty); if (disc == NULL) /* !TTY_LDISC */ return; spin_lock_irqsave(&tty->buf.lock, flags); - /* So we know a flush is running */ - set_bit(TTY_FLUSHING, &tty->flags); - head = tty->buf.head; - if (head != NULL) { - tty->buf.head = NULL; - for (;;) { - int count = head->commit - head->read; + + if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { + struct tty_buffer *head; + while ((head = tty->buf.head) != NULL) { + int count; + char *char_buf; + unsigned char *flag_buf; + + count = head->commit - head->read; if (!count) { if (head->next == NULL) break; - tbuf = head; - head = head->next; - tty_buffer_free(tty, tbuf); + tty->buf.head = head->next; + tty_buffer_free(tty, head); continue; } /* Ldisc or user is trying to flush the buffers @@ -445,9 +443,9 @@ static void flush_to_ldisc(struct work_struct *work) flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); } - /* Restore the queue head */ - tty->buf.head = head; + clear_bit(TTY_FLUSHING, &tty->flags); } + /* We may have a deferred request to flush the input buffer, if so pull the chain under the lock and empty the queue */ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { @@ -455,7 +453,6 @@ static void flush_to_ldisc(struct work_struct *work) clear_bit(TTY_FLUSHPENDING, &tty->flags); wake_up(&tty->read_wait); } - clear_bit(TTY_FLUSHING, &tty->flags); spin_unlock_irqrestore(&tty->buf.lock, flags); tty_ldisc_deref(disc); @@ -471,7 +468,7 @@ static void flush_to_ldisc(struct work_struct *work) */ void tty_flush_to_ldisc(struct tty_struct *tty) { - flush_to_ldisc(&tty->buf.work.work); + flush_delayed_work(&tty->buf.work); } /** diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index a4bbb28f10b..c63f3d33914 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c @@ -219,8 +219,14 @@ int tty_port_block_til_ready(struct tty_port *port, /* if non-blocking mode is set we can pass directly to open unless the port has just hung up or is in another error state */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { + if (tty->flags & (1 << TTY_IO_ERROR)) { + port->flags |= ASYNC_NORMAL_ACTIVE; + return 0; + } + if (filp->f_flags & O_NONBLOCK) { + /* Indicate we are open */ + if (tty->termios->c_cflag & CBAUD) + tty_port_raise_dtr_rts(port); port->flags |= ASYNC_NORMAL_ACTIVE; return 0; } diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 0d328b59568..a035ae39a35 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -31,7 +31,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/virtio.h> -#include <linux/virtio_ids.h> #include <linux/virtio_console.h> #include "hvc_console.h" diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 0c80c68cd04..1e3d728dbf7 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -161,6 +161,8 @@ static void set_palette(struct vc_data *vc); static int printable; /* Is console ready for printing? */ int default_utf8 = true; module_param(default_utf8, int, S_IRUGO | S_IWUSR); +int global_cursor_default = -1; +module_param(global_cursor_default, int, S_IRUGO | S_IWUSR); /* * ignore_poke: don't unblank the screen when things are typed. This is @@ -775,6 +777,12 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ vc_cons[currcons].d = NULL; return -ENOMEM; } + + /* If no drivers have overridden us and the user didn't pass a + boot option, default to displaying the cursor */ + if (global_cursor_default == -1) + global_cursor_default = 1; + vc_init(vc, vc->vc_rows, vc->vc_cols, 1); vcs_make_sysfs(currcons); atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); @@ -1616,7 +1624,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) vc->vc_decscnm = 0; vc->vc_decom = 0; vc->vc_decawm = 1; - vc->vc_deccm = 1; + vc->vc_deccm = global_cursor_default; vc->vc_decim = 0; set_kbd(vc, decarm); @@ -4078,6 +4086,7 @@ EXPORT_SYMBOL(fg_console); EXPORT_SYMBOL(console_blank_hook); EXPORT_SYMBOL(console_blanked); EXPORT_SYMBOL(vc_cons); +EXPORT_SYMBOL(global_cursor_default); #ifndef VT_SINGLE_DRIVER EXPORT_SYMBOL(take_over_console); EXPORT_SYMBOL(give_up_console); diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 6b36ee56e6f..6aa10284104 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -103,8 +103,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new) ve->event.event = event; /* kernel view is consoles 0..n-1, user space view is console 1..n with 0 meaning current, so we must bias */ - ve->event.old = old + 1; - ve->event.new = new + 1; + ve->event.oldev = old + 1; + ve->event.newev = new + 1; wake = 1; ve->done = 1; } @@ -186,7 +186,7 @@ int vt_waitactive(int n) vt_event_wait(&vw); if (vw.done == 0) return -EINTR; - } while (vw.event.new != n); + } while (vw.event.newev != n); return 0; } @@ -1532,7 +1532,7 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file, case PIO_UNIMAP: case GIO_UNIMAP: - ret = do_unimap_ioctl(cmd, up, perm, vc); + ret = compat_unimap_ioctl(cmd, up, perm, vc); break; /* |