diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/Makefile | 2 | ||||
-rw-r--r-- | drivers/char/agp/agp.h | 3 | ||||
-rw-r--r-- | drivers/char/agp/amd-k7-agp.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/ati-agp.c | 3 | ||||
-rw-r--r-- | drivers/char/agp/efficeon-agp.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/hp-agp.c | 1 | ||||
-rw-r--r-- | drivers/char/agp/i460-agp.c | 4 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 21 | ||||
-rw-r--r-- | drivers/char/agp/nvidia-agp.c | 3 | ||||
-rw-r--r-- | drivers/char/agp/via-agp.c | 5 | ||||
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 13 | ||||
-rw-r--r-- | drivers/char/drm/i915_drv.h | 6 | ||||
-rw-r--r-- | drivers/char/drm/i915_irq.c | 12 | ||||
-rw-r--r-- | drivers/char/drm/via_dmablit.c | 2 | ||||
-rw-r--r-- | drivers/char/hpet.c | 12 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 3 | ||||
-rw-r--r-- | drivers/char/lcd.c | 1 | ||||
-rw-r--r-- | drivers/char/mspec.c | 65 | ||||
-rw-r--r-- | drivers/char/random.c | 10 | ||||
-rw-r--r-- | drivers/char/sonypi.c | 2 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 6 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 14 | ||||
-rw-r--r-- | drivers/char/vt_ioctl.c | 19 |
23 files changed, 150 insertions, 61 deletions
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index d68ddbe70f7..c78ff26647e 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -129,7 +129,7 @@ $(obj)/defkeymap.o: $(obj)/defkeymap.c ifdef GENERATE_KEYMAP -$(obj)/defkeymap.c $(obj)/%.c: $(src)/%.map +$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map loadkeys --mktable $< > $@.tmp sed -e 's/^static *//' $@.tmp > $@ rm $@.tmp diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 35ab1a9f8e8..8955e7ff759 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -176,7 +176,7 @@ struct agp_bridge_data { #define I830_GMCH_MEM_MASK 0x1 #define I830_GMCH_MEM_64M 0x1 #define I830_GMCH_MEM_128M 0 -#define I830_GMCH_GMS_MASK 0xF0 +#define I830_GMCH_GMS_MASK 0x70 #define I830_GMCH_GMS_DISABLED 0x00 #define I830_GMCH_GMS_LOCAL 0x10 #define I830_GMCH_GMS_STOLEN_512 0x20 @@ -190,6 +190,7 @@ struct agp_bridge_data { #define INTEL_I830_ERRSTS 0x92 /* Intel 855GM/852GM registers */ +#define I855_GMCH_GMS_MASK 0xF0 #define I855_GMCH_GMS_STOLEN_0M 0x0 #define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) #define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index df0ddf14b85..f60bca70d1f 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -223,6 +223,8 @@ static int amd_irongate_configure(void) pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!amd_irongate_private.registers) + return -ENOMEM; /* Write out the address of the gatt table */ writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index da7513d7b4e..2d46b713c8f 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -213,6 +213,9 @@ static int ati_configure(void) temp = (temp & 0xfffff000); ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!ati_generic_private.registers) + return -ENOMEM; + if (is_r200()) pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); else diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index df8da726285..d78cd09186a 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -375,6 +375,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, if (!r->start && r->end) { if (pci_assign_resource(pdev, 0)) { printk(KERN_ERR PFX "could not assign resource 0\n"); + agp_put_bridge(bridge); return -ENODEV; } } @@ -386,6 +387,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, */ if (pci_enable_device(pdev)) { printk(KERN_ERR PFX "Unable to Enable PCI device\n"); + agp_put_bridge(bridge); return -ENODEV; } diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index bcdb149c817..313a133a117 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -221,6 +221,7 @@ hp_zx1_lba_init (u64 hpa) if (cap != PCI_CAP_ID_AGP) { printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n", cap, hp->lba_cap_offset); + iounmap(hp->lba_regs); return -ENODEV; } diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 53354bf83af..75d2aca6353 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -249,6 +249,10 @@ static int i460_create_gatt_table (struct agp_bridge_data *bridge) num_entries = A_SIZE_8(temp)->num_entries; i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); + if (!i460.gatt) { + printk(KERN_ERR PFX "ioremap failed\n"); + return -ENOMEM; + } /* These are no good, the should be removed from the agp_bridge strucure... */ agp_bridge->gatt_table_real = NULL; diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 294cdbf4d44..141ca176c39 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -506,7 +506,7 @@ static void intel_i830_init_gtt_entries(void) break; } } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + switch (gmch_ctrl & I855_GMCH_GMS_MASK) { case I855_GMCH_GMS_STOLEN_1M: gtt_entries = MB(1) - KB(size); break; @@ -914,6 +914,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) struct aper_size_info_fixed *size; int num_entries; u32 temp, temp2; + int gtt_map_size = 256 * 1024; size = agp_bridge->current_size; page_order = size->page_order; @@ -923,15 +924,19 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2); - intel_private.gtt = ioremap(temp2, 256 * 1024); + if (IS_G33) + gtt_map_size = 1024 * 1024; /* 1M on G33 */ + intel_private.gtt = ioremap(temp2, gtt_map_size); if (!intel_private.gtt) return -ENOMEM; temp &= 0xfff80000; intel_private.registers = ioremap(temp,128 * 4096); - if (!intel_private.registers) + if (!intel_private.registers) { + iounmap(intel_private.gtt); return -ENOMEM; + } temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ @@ -985,13 +990,15 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) temp &= 0xfff00000; intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024); - if (!intel_private.gtt) - return -ENOMEM; + if (!intel_private.gtt) + return -ENOMEM; intel_private.registers = ioremap(temp,128 * 4096); - if (!intel_private.registers) - return -ENOMEM; + if (!intel_private.registers) { + iounmap(intel_private.gtt); + return -ENOMEM; + } temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 6cd7373dcdf..225ed2a53d4 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -157,6 +157,9 @@ static int nvidia_configure(void) nvidia_private.aperture = (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE); + if (!nvidia_private.aperture) + return -ENOMEM; + return 0; } diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 9aaf401a897..0ecc54d327b 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -399,6 +399,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata = .device_id = PCI_DEVICE_ID_VIA_P4M890, .chipset_name = "P4M890", }, + /* P4M900 */ + { + .device_id = PCI_DEVICE_ID_VIA_VT3364, + .chipset_name = "P4M900", + }, { }, /* dummy final entry, always present */ }; diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 923174c54a1..c115b39b851 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -177,8 +177,14 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset, MTRR_TYPE_WRCOMB, 1); } } - if (map->type == _DRM_REGISTERS) + if (map->type == _DRM_REGISTERS) { map->handle = ioremap(map->offset, map->size); + if (!map->handle) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + return -ENOMEM; + } + } + break; case _DRM_SHM: list = drm_find_matching_map(dev, map); @@ -479,11 +485,6 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, return -EINVAL; } - if (!map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - /* Register and framebuffer maps are permanent */ if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { mutex_unlock(&dev->struct_mutex); diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 737088bd078..28b98733beb 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h @@ -210,6 +210,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define I915REG_INT_MASK_R 0x020a8 #define I915REG_INT_ENABLE_R 0x020a0 +#define I915REG_PIPEASTAT 0x70024 +#define I915REG_PIPEBSTAT 0x71024 + +#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) +#define I915_VBLANK_CLEAR (1UL<<1) + #define SRX_INDEX 0x3c4 #define SRX_DATA 0x3c5 #define SR01 1 diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 4b4b2ce8986..bb8e9e9c820 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c @@ -214,6 +214,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; u16 temp; + u32 pipea_stats, pipeb_stats; + + pipea_stats = I915_READ(I915REG_PIPEASTAT); + pipeb_stats = I915_READ(I915REG_PIPEBSTAT); temp = I915_READ16(I915REG_INT_IDENTITY_R); @@ -225,6 +229,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) return IRQ_NONE; I915_WRITE16(I915REG_INT_IDENTITY_R, temp); + (void) I915_READ16(I915REG_INT_IDENTITY_R); + DRM_READMEMORYBARRIER(); dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); @@ -252,6 +258,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (dev_priv->swaps_pending > 0) drm_locked_tasklet(dev, i915_vblank_tasklet); + I915_WRITE(I915REG_PIPEASTAT, + pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); + I915_WRITE(I915REG_PIPEBSTAT, + pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| + I915_VBLANK_CLEAR); } return IRQ_HANDLED; diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 832de1d9ba7..3dd1ed3d1bf 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c @@ -560,7 +560,7 @@ via_init_dmablit(struct drm_device *dev) blitq->head = 0; blitq->cur = 0; blitq->serviced = 0; - blitq->num_free = VIA_NUM_BLIT_SLOTS; + blitq->num_free = VIA_NUM_BLIT_SLOTS - 1; blitq->num_outstanding = 0; blitq->is_active = 0; blitq->aborting = 0; diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 77bf4aa217a..4c16778e3f8 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -62,6 +62,8 @@ static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; +/* This clocksource driver currently only works on ia64 */ +#ifdef CONFIG_IA64 static void __iomem *hpet_mctr; static cycle_t read_hpet(void) @@ -79,6 +81,7 @@ static struct clocksource clocksource_hpet = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; static struct clocksource *hpet_clocksource; +#endif /* A lock for concurrent access by app and isr hpet activity. */ static DEFINE_SPINLOCK(hpet_lock); @@ -909,6 +912,8 @@ int hpet_alloc(struct hpet_data *hdp) hpetp->hp_delta = hpet_calibrate(hpetp); +/* This clocksource driver currently only works on ia64 */ +#ifdef CONFIG_IA64 if (!hpet_clocksource) { hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc; CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr); @@ -918,6 +923,7 @@ int hpet_alloc(struct hpet_data *hdp) hpetp->hp_clocksource = &clocksource_hpet; hpet_clocksource = &clocksource_hpet; } +#endif return 0; } @@ -940,14 +946,14 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) printk(KERN_DEBUG "%s: 0x%lx is busy\n", __FUNCTION__, hdp->hd_phys_address); iounmap(hdp->hd_address); - return -EBUSY; + return AE_ALREADY_EXISTS; } } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) { struct acpi_resource_fixed_memory32 *fixmem32; fixmem32 = &res->data.fixed_memory32; if (!fixmem32) - return -EINVAL; + return AE_NO_MEMORY; hdp->hd_phys_address = fixmem32->address; hdp->hd_address = ioremap(fixmem32->address, @@ -957,7 +963,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) printk(KERN_DEBUG "%s: 0x%lx is busy\n", __FUNCTION__, hdp->hd_phys_address); iounmap(hdp->hd_address); - return -EBUSY; + return AE_ALREADY_EXISTS; } } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { struct acpi_resource_extended_irq *irqp; diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 9b07f785106..dd441ff4af5 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2215,7 +2215,8 @@ static int ipmi_pci_resume(struct pci_dev *pdev) static struct pci_device_id ipmi_pci_devices[] = { { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, - { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) } + { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }, + { 0, } }; MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 1f0962616ee..4fe9206f84d 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c @@ -25,7 +25,6 @@ #include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> -#include <linux/delay.h> #include "lcd.h" diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index c08a4152ee8..04ac155d3a0 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c @@ -67,7 +67,7 @@ /* * Page types allocated by the device. */ -enum { +enum mspec_page_type { MSPEC_FETCHOP = 1, MSPEC_CACHED, MSPEC_UNCACHED @@ -83,15 +83,25 @@ static int is_sn2; * One of these structures is allocated when an mspec region is mmaped. The * structure is pointed to by the vma->vm_private_data field in the vma struct. * This structure is used to record the addresses of the mspec pages. + * This structure is shared by all vma's that are split off from the + * original vma when split_vma()'s are done. + * + * The refcnt is incremented atomically because mm->mmap_sem does not + * protect in fork case where multiple tasks share the vma_data. */ struct vma_data { atomic_t refcnt; /* Number of vmas sharing the data. */ - spinlock_t lock; /* Serialize access to the vma. */ + spinlock_t lock; /* Serialize access to this structure. */ int count; /* Number of pages allocated. */ - int type; /* Type of pages allocated. */ + enum mspec_page_type type; /* Type of pages allocated. */ + int flags; /* See VMD_xxx below. */ + unsigned long vm_start; /* Original (unsplit) base. */ + unsigned long vm_end; /* Original (unsplit) end. */ unsigned long maddr[0]; /* Array of MSPEC addresses. */ }; +#define VMD_VMALLOCED 0x1 /* vmalloc'd rather than kmalloc'd */ + /* used on shub2 to clear FOP cache in the HUB */ static unsigned long scratch_page[MAX_NUMNODES]; #define SH2_AMO_CACHE_ENTRIES 4 @@ -129,8 +139,8 @@ mspec_zero_block(unsigned long addr, int len) * mspec_open * * Called when a device mapping is created by a means other than mmap - * (via fork, etc.). Increments the reference count on the underlying - * mspec data so it is not freed prematurely. + * (via fork, munmap, etc.). Increments the reference count on the + * underlying mspec data so it is not freed prematurely. */ static void mspec_open(struct vm_area_struct *vma) @@ -145,43 +155,43 @@ mspec_open(struct vm_area_struct *vma) * mspec_close * * Called when unmapping a device mapping. Frees all mspec pages - * belonging to the vma. + * belonging to all the vma's sharing this vma_data structure. */ static void mspec_close(struct vm_area_struct *vma) { struct vma_data *vdata; - int i, pages, result, vdata_size; + int index, last_index; + unsigned long my_page; vdata = vma->vm_private_data; + if (!atomic_dec_and_test(&vdata->refcnt)) return; - pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; - vdata_size = sizeof(struct vma_data) + pages * sizeof(long); - for (i = 0; i < pages; i++) { - if (vdata->maddr[i] == 0) + last_index = (vdata->vm_end - vdata->vm_start) >> PAGE_SHIFT; + for (index = 0; index < last_index; index++) { + if (vdata->maddr[index] == 0) continue; /* * Clear the page before sticking it back * into the pool. */ - result = mspec_zero_block(vdata->maddr[i], PAGE_SIZE); - if (!result) - uncached_free_page(vdata->maddr[i]); + my_page = vdata->maddr[index]; + vdata->maddr[index] = 0; + if (!mspec_zero_block(my_page, PAGE_SIZE)) + uncached_free_page(my_page); else printk(KERN_WARNING "mspec_close(): " - "failed to zero page %i\n", - result); + "failed to zero page %ld\n", my_page); } - if (vdata_size <= PAGE_SIZE) - kfree(vdata); - else + if (vdata->flags & VMD_VMALLOCED) vfree(vdata); + else + kfree(vdata); } - /* * mspec_nopfn * @@ -195,7 +205,8 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) int index; struct vma_data *vdata = vma->vm_private_data; - index = (address - vma->vm_start) >> PAGE_SHIFT; + BUG_ON(address < vdata->vm_start || address >= vdata->vm_end); + index = (address - vdata->vm_start) >> PAGE_SHIFT; maddr = (volatile unsigned long) vdata->maddr[index]; if (maddr == 0) { maddr = uncached_alloc_page(numa_node_id()); @@ -237,10 +248,11 @@ static struct vm_operations_struct mspec_vm_ops = { * underlying pages. */ static int -mspec_mmap(struct file *file, struct vm_area_struct *vma, int type) +mspec_mmap(struct file *file, struct vm_area_struct *vma, + enum mspec_page_type type) { struct vma_data *vdata; - int pages, vdata_size; + int pages, vdata_size, flags = 0; if (vma->vm_pgoff != 0) return -EINVAL; @@ -255,12 +267,17 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, int type) vdata_size = sizeof(struct vma_data) + pages * sizeof(long); if (vdata_size <= PAGE_SIZE) vdata = kmalloc(vdata_size, GFP_KERNEL); - else + else { vdata = vmalloc(vdata_size); + flags = VMD_VMALLOCED; + } if (!vdata) return -ENOMEM; memset(vdata, 0, vdata_size); + vdata->vm_start = vma->vm_start; + vdata->vm_end = vma->vm_end; + vdata->flags = flags; vdata->type = type; spin_lock_init(&vdata->lock); vdata->refcnt = ATOMIC_INIT(1); diff --git a/drivers/char/random.c b/drivers/char/random.c index 397c714cf2b..af274e5a25e 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1550,11 +1550,13 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, * As close as possible to RFC 793, which * suggests using a 250 kHz clock. * Further reading shows this assumes 2 Mb/s networks. - * For 10 Gb/s Ethernet, a 1 GHz clock is appropriate. - * That's funny, Linux has one built in! Use it! - * (Networks are faster now - should this be increased?) + * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. + * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but + * we also need to limit the resolution so that the u32 seq + * overlaps less than one time per MSL (2 minutes). + * Choosing a clock of 64 ns period is OK. (period of 274 s) */ - seq += ktime_get_real().tv64; + seq += ktime_get_real().tv64 >> 6; #if 0 printk("init_seq(%lx, %lx, %d, %d) = %d\n", saddr, daddr, sport, dport, seq); diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index aeec67e2726..859858561ab 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -875,7 +875,7 @@ found: #ifdef CONFIG_ACPI if (sonypi_acpi_device) - acpi_bus_generate_event(sonypi_acpi_device, 1, event); + acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); #endif kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 51ea93cab6c..9c867cf6de6 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2063,8 +2063,7 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*tp_loc) { - tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), - GFP_KERNEL); + tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); if (!tp) goto free_mem_out; *tp = driver->init_termios; @@ -2094,8 +2093,7 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*o_tp_loc) { - o_tp = (struct ktermios *) - kmalloc(sizeof(struct ktermios), GFP_KERNEL); + o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); if (!o_tp) goto free_mem_out; *o_tp = driver->other->init_termios; diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 3423e9ee648..3ee73cf64bd 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -795,6 +795,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, if (L_ICANON(tty)) retval = inq_canon(tty); return put_user(retval, (unsigned int __user *) arg); +#ifndef TCGETS2 case TIOCGLCKTRMIOS: if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) return -EFAULT; @@ -806,6 +807,19 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg)) return -EFAULT; return 0; +#else + case TIOCGLCKTRMIOS: + if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) + return -EFAULT; + return 0; + + case TIOCSLCKTRMIOS: + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg)) + return -EFAULT; + return 0; +#endif case TIOCPKT: { diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index c6f6f420973..7a61a2a9aaf 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -770,6 +770,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, /* * Switching-from response */ + acquire_console_sem(); if (vc->vt_newvt >= 0) { if (arg == 0) /* @@ -784,7 +785,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, * complete the switch. */ int newvt; - acquire_console_sem(); newvt = vc->vt_newvt; vc->vt_newvt = -1; i = vc_allocate(newvt); @@ -798,7 +798,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, * other console switches.. */ complete_change_console(vc_cons[newvt].d); - release_console_sem(); } } @@ -810,9 +809,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, /* * If it's just an ACK, ignore it */ - if (arg != VT_ACKACQ) + if (arg != VT_ACKACQ) { + release_console_sem(); return -EINVAL; + } } + release_console_sem(); return 0; @@ -1030,7 +1032,7 @@ static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue); /* * Sleeps until a vt is activated, or the task is interrupted. Returns - * 0 if activation, -EINTR if interrupted. + * 0 if activation, -EINTR if interrupted by a signal handler. */ int vt_waitactive(int vt) { @@ -1055,7 +1057,7 @@ int vt_waitactive(int vt) break; } release_console_sem(); - retval = -EINTR; + retval = -ERESTARTNOHAND; if (signal_pending(current)) break; schedule(); @@ -1208,15 +1210,18 @@ void change_console(struct vc_data *new_vc) /* * Send the signal as privileged - kill_pid() will * tell us if the process has gone or something else - * is awry + * is awry. + * + * We need to set vt_newvt *before* sending the signal or we + * have a race. */ + vc->vt_newvt = new_vc->vc_num; if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { /* * It worked. Mark the vt to switch to and * return. The process needs to send us a * VT_RELDISP ioctl to complete the switch. */ - vc->vt_newvt = new_vc->vc_num; return; } |