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 d68ddbe70f73..c78ff26647ee 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -129,7 +129,7 @@ $(obj)/defkeymap.o: $(obj)/defkeymap.c | |||
129 | 129 | ||
130 | ifdef GENERATE_KEYMAP | 130 | ifdef GENERATE_KEYMAP |
131 | 131 | ||
132 | $(obj)/defkeymap.c $(obj)/%.c: $(src)/%.map | 132 | $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map |
133 | loadkeys --mktable $< > $@.tmp | 133 | loadkeys --mktable $< > $@.tmp |
134 | sed -e 's/^static *//' $@.tmp > $@ | 134 | sed -e 's/^static *//' $@.tmp > $@ |
135 | rm $@.tmp | 135 | rm $@.tmp |
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 35ab1a9f8e8b..8955e7ff759a 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -176,7 +176,7 @@ struct agp_bridge_data { | |||
176 | #define I830_GMCH_MEM_MASK 0x1 | 176 | #define I830_GMCH_MEM_MASK 0x1 |
177 | #define I830_GMCH_MEM_64M 0x1 | 177 | #define I830_GMCH_MEM_64M 0x1 |
178 | #define I830_GMCH_MEM_128M 0 | 178 | #define I830_GMCH_MEM_128M 0 |
179 | #define I830_GMCH_GMS_MASK 0xF0 | 179 | #define I830_GMCH_GMS_MASK 0x70 |
180 | #define I830_GMCH_GMS_DISABLED 0x00 | 180 | #define I830_GMCH_GMS_DISABLED 0x00 |
181 | #define I830_GMCH_GMS_LOCAL 0x10 | 181 | #define I830_GMCH_GMS_LOCAL 0x10 |
182 | #define I830_GMCH_GMS_STOLEN_512 0x20 | 182 | #define I830_GMCH_GMS_STOLEN_512 0x20 |
@@ -190,6 +190,7 @@ struct agp_bridge_data { | |||
190 | #define INTEL_I830_ERRSTS 0x92 | 190 | #define INTEL_I830_ERRSTS 0x92 |
191 | 191 | ||
192 | /* Intel 855GM/852GM registers */ | 192 | /* Intel 855GM/852GM registers */ |
193 | #define I855_GMCH_GMS_MASK 0xF0 | ||
193 | #define I855_GMCH_GMS_STOLEN_0M 0x0 | 194 | #define I855_GMCH_GMS_STOLEN_0M 0x0 |
194 | #define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) | 195 | #define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) |
195 | #define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) | 196 | #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 df0ddf14b85c..f60bca70d1fb 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) | |||
223 | pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); | 223 | pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); |
224 | temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); | 224 | temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); |
225 | amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); | 225 | amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); |
226 | if (!amd_irongate_private.registers) | ||
227 | return -ENOMEM; | ||
226 | 228 | ||
227 | /* Write out the address of the gatt table */ | 229 | /* Write out the address of the gatt table */ |
228 | writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); | 230 | 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 da7513d7b4e7..2d46b713c8f2 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -213,6 +213,9 @@ static int ati_configure(void) | |||
213 | temp = (temp & 0xfffff000); | 213 | temp = (temp & 0xfffff000); |
214 | ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); | 214 | ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); |
215 | 215 | ||
216 | if (!ati_generic_private.registers) | ||
217 | return -ENOMEM; | ||
218 | |||
216 | if (is_r200()) | 219 | if (is_r200()) |
217 | pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); | 220 | pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); |
218 | else | 221 | else |
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index df8da7262853..d78cd09186aa 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, | |||
375 | if (!r->start && r->end) { | 375 | if (!r->start && r->end) { |
376 | if (pci_assign_resource(pdev, 0)) { | 376 | if (pci_assign_resource(pdev, 0)) { |
377 | printk(KERN_ERR PFX "could not assign resource 0\n"); | 377 | printk(KERN_ERR PFX "could not assign resource 0\n"); |
378 | agp_put_bridge(bridge); | ||
378 | return -ENODEV; | 379 | return -ENODEV; |
379 | } | 380 | } |
380 | } | 381 | } |
@@ -386,6 +387,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, | |||
386 | */ | 387 | */ |
387 | if (pci_enable_device(pdev)) { | 388 | if (pci_enable_device(pdev)) { |
388 | printk(KERN_ERR PFX "Unable to Enable PCI device\n"); | 389 | printk(KERN_ERR PFX "Unable to Enable PCI device\n"); |
390 | agp_put_bridge(bridge); | ||
389 | return -ENODEV; | 391 | return -ENODEV; |
390 | } | 392 | } |
391 | 393 | ||
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index bcdb149c8179..313a133a1172 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) | |||
221 | if (cap != PCI_CAP_ID_AGP) { | 221 | if (cap != PCI_CAP_ID_AGP) { |
222 | printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n", | 222 | printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n", |
223 | cap, hp->lba_cap_offset); | 223 | cap, hp->lba_cap_offset); |
224 | iounmap(hp->lba_regs); | ||
224 | return -ENODEV; | 225 | return -ENODEV; |
225 | } | 226 | } |
226 | 227 | ||
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 53354bf83af7..75d2aca6353d 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) | |||
249 | num_entries = A_SIZE_8(temp)->num_entries; | 249 | num_entries = A_SIZE_8(temp)->num_entries; |
250 | 250 | ||
251 | i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); | 251 | i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); |
252 | if (!i460.gatt) { | ||
253 | printk(KERN_ERR PFX "ioremap failed\n"); | ||
254 | return -ENOMEM; | ||
255 | } | ||
252 | 256 | ||
253 | /* These are no good, the should be removed from the agp_bridge strucure... */ | 257 | /* These are no good, the should be removed from the agp_bridge strucure... */ |
254 | agp_bridge->gatt_table_real = NULL; | 258 | agp_bridge->gatt_table_real = NULL; |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 294cdbf4d44d..141ca176c397 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) | |||
506 | break; | 506 | break; |
507 | } | 507 | } |
508 | } else { | 508 | } else { |
509 | switch (gmch_ctrl & I830_GMCH_GMS_MASK) { | 509 | switch (gmch_ctrl & I855_GMCH_GMS_MASK) { |
510 | case I855_GMCH_GMS_STOLEN_1M: | 510 | case I855_GMCH_GMS_STOLEN_1M: |
511 | gtt_entries = MB(1) - KB(size); | 511 | gtt_entries = MB(1) - KB(size); |
512 | break; | 512 | break; |
@@ -914,6 +914,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
914 | struct aper_size_info_fixed *size; | 914 | struct aper_size_info_fixed *size; |
915 | int num_entries; | 915 | int num_entries; |
916 | u32 temp, temp2; | 916 | u32 temp, temp2; |
917 | int gtt_map_size = 256 * 1024; | ||
917 | 918 | ||
918 | size = agp_bridge->current_size; | 919 | size = agp_bridge->current_size; |
919 | page_order = size->page_order; | 920 | page_order = size->page_order; |
@@ -923,15 +924,19 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
923 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | 924 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); |
924 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2); | 925 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2); |
925 | 926 | ||
926 | intel_private.gtt = ioremap(temp2, 256 * 1024); | 927 | if (IS_G33) |
928 | gtt_map_size = 1024 * 1024; /* 1M on G33 */ | ||
929 | intel_private.gtt = ioremap(temp2, gtt_map_size); | ||
927 | if (!intel_private.gtt) | 930 | if (!intel_private.gtt) |
928 | return -ENOMEM; | 931 | return -ENOMEM; |
929 | 932 | ||
930 | temp &= 0xfff80000; | 933 | temp &= 0xfff80000; |
931 | 934 | ||
932 | intel_private.registers = ioremap(temp,128 * 4096); | 935 | intel_private.registers = ioremap(temp,128 * 4096); |
933 | if (!intel_private.registers) | 936 | if (!intel_private.registers) { |
937 | iounmap(intel_private.gtt); | ||
934 | return -ENOMEM; | 938 | return -ENOMEM; |
939 | } | ||
935 | 940 | ||
936 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | 941 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; |
937 | global_cache_flush(); /* FIXME: ? */ | 942 | global_cache_flush(); /* FIXME: ? */ |
@@ -985,13 +990,15 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) | |||
985 | temp &= 0xfff00000; | 990 | temp &= 0xfff00000; |
986 | intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024); | 991 | intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024); |
987 | 992 | ||
988 | if (!intel_private.gtt) | 993 | if (!intel_private.gtt) |
989 | return -ENOMEM; | 994 | return -ENOMEM; |
990 | 995 | ||
991 | 996 | ||
992 | intel_private.registers = ioremap(temp,128 * 4096); | 997 | intel_private.registers = ioremap(temp,128 * 4096); |
993 | if (!intel_private.registers) | 998 | if (!intel_private.registers) { |
994 | return -ENOMEM; | 999 | iounmap(intel_private.gtt); |
1000 | return -ENOMEM; | ||
1001 | } | ||
995 | 1002 | ||
996 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | 1003 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; |
997 | global_cache_flush(); /* FIXME: ? */ | 1004 | global_cache_flush(); /* FIXME: ? */ |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 6cd7373dcdf4..225ed2a53d45 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -157,6 +157,9 @@ static int nvidia_configure(void) | |||
157 | nvidia_private.aperture = | 157 | nvidia_private.aperture = |
158 | (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE); | 158 | (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE); |
159 | 159 | ||
160 | if (!nvidia_private.aperture) | ||
161 | return -ENOMEM; | ||
162 | |||
160 | return 0; | 163 | return 0; |
161 | } | 164 | } |
162 | 165 | ||
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 9aaf401a8975..0ecc54d327bc 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 = | |||
399 | .device_id = PCI_DEVICE_ID_VIA_P4M890, | 399 | .device_id = PCI_DEVICE_ID_VIA_P4M890, |
400 | .chipset_name = "P4M890", | 400 | .chipset_name = "P4M890", |
401 | }, | 401 | }, |
402 | /* P4M900 */ | ||
403 | { | ||
404 | .device_id = PCI_DEVICE_ID_VIA_VT3364, | ||
405 | .chipset_name = "P4M900", | ||
406 | }, | ||
402 | { }, /* dummy final entry, always present */ | 407 | { }, /* dummy final entry, always present */ |
403 | }; | 408 | }; |
404 | 409 | ||
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 923174c54a1c..c115b39b8517 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, | |||
177 | MTRR_TYPE_WRCOMB, 1); | 177 | MTRR_TYPE_WRCOMB, 1); |
178 | } | 178 | } |
179 | } | 179 | } |
180 | if (map->type == _DRM_REGISTERS) | 180 | if (map->type == _DRM_REGISTERS) { |
181 | map->handle = ioremap(map->offset, map->size); | 181 | map->handle = ioremap(map->offset, map->size); |
182 | if (!map->handle) { | ||
183 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | ||
184 | return -ENOMEM; | ||
185 | } | ||
186 | } | ||
187 | |||
182 | break; | 188 | break; |
183 | case _DRM_SHM: | 189 | case _DRM_SHM: |
184 | list = drm_find_matching_map(dev, map); | 190 | list = drm_find_matching_map(dev, map); |
@@ -479,11 +485,6 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, | |||
479 | return -EINVAL; | 485 | return -EINVAL; |
480 | } | 486 | } |
481 | 487 | ||
482 | if (!map) { | ||
483 | mutex_unlock(&dev->struct_mutex); | ||
484 | return -EINVAL; | ||
485 | } | ||
486 | |||
487 | /* Register and framebuffer maps are permanent */ | 488 | /* Register and framebuffer maps are permanent */ |
488 | if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { | 489 | if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { |
489 | mutex_unlock(&dev->struct_mutex); | 490 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index 737088bd0780..28b98733beb8 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); | |||
210 | #define I915REG_INT_MASK_R 0x020a8 | 210 | #define I915REG_INT_MASK_R 0x020a8 |
211 | #define I915REG_INT_ENABLE_R 0x020a0 | 211 | #define I915REG_INT_ENABLE_R 0x020a0 |
212 | 212 | ||
213 | #define I915REG_PIPEASTAT 0x70024 | ||
214 | #define I915REG_PIPEBSTAT 0x71024 | ||
215 | |||
216 | #define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17) | ||
217 | #define I915_VBLANK_CLEAR (1UL<<1) | ||
218 | |||
213 | #define SRX_INDEX 0x3c4 | 219 | #define SRX_INDEX 0x3c4 |
214 | #define SRX_DATA 0x3c5 | 220 | #define SRX_DATA 0x3c5 |
215 | #define SR01 1 | 221 | #define SR01 1 |
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index 4b4b2ce89863..bb8e9e9c8201 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) | |||
214 | struct drm_device *dev = (struct drm_device *) arg; | 214 | struct drm_device *dev = (struct drm_device *) arg; |
215 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 215 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
216 | u16 temp; | 216 | u16 temp; |
217 | u32 pipea_stats, pipeb_stats; | ||
218 | |||
219 | pipea_stats = I915_READ(I915REG_PIPEASTAT); | ||
220 | pipeb_stats = I915_READ(I915REG_PIPEBSTAT); | ||
217 | 221 | ||
218 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | 222 | temp = I915_READ16(I915REG_INT_IDENTITY_R); |
219 | 223 | ||
@@ -225,6 +229,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
225 | return IRQ_NONE; | 229 | return IRQ_NONE; |
226 | 230 | ||
227 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | 231 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); |
232 | (void) I915_READ16(I915REG_INT_IDENTITY_R); | ||
233 | DRM_READMEMORYBARRIER(); | ||
228 | 234 | ||
229 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 235 | dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
230 | 236 | ||
@@ -252,6 +258,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
252 | 258 | ||
253 | if (dev_priv->swaps_pending > 0) | 259 | if (dev_priv->swaps_pending > 0) |
254 | drm_locked_tasklet(dev, i915_vblank_tasklet); | 260 | drm_locked_tasklet(dev, i915_vblank_tasklet); |
261 | I915_WRITE(I915REG_PIPEASTAT, | ||
262 | pipea_stats|I915_VBLANK_INTERRUPT_ENABLE| | ||
263 | I915_VBLANK_CLEAR); | ||
264 | I915_WRITE(I915REG_PIPEBSTAT, | ||
265 | pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE| | ||
266 | I915_VBLANK_CLEAR); | ||
255 | } | 267 | } |
256 | 268 | ||
257 | return IRQ_HANDLED; | 269 | return IRQ_HANDLED; |
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 832de1d9ba7e..3dd1ed3d1bf5 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) | |||
560 | blitq->head = 0; | 560 | blitq->head = 0; |
561 | blitq->cur = 0; | 561 | blitq->cur = 0; |
562 | blitq->serviced = 0; | 562 | blitq->serviced = 0; |
563 | blitq->num_free = VIA_NUM_BLIT_SLOTS; | 563 | blitq->num_free = VIA_NUM_BLIT_SLOTS - 1; |
564 | blitq->num_outstanding = 0; | 564 | blitq->num_outstanding = 0; |
565 | blitq->is_active = 0; | 565 | blitq->is_active = 0; |
566 | blitq->aborting = 0; | 566 | blitq->aborting = 0; |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 77bf4aa217a8..4c16778e3f84 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -62,6 +62,8 @@ | |||
62 | 62 | ||
63 | static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; | 63 | static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; |
64 | 64 | ||
65 | /* This clocksource driver currently only works on ia64 */ | ||
66 | #ifdef CONFIG_IA64 | ||
65 | static void __iomem *hpet_mctr; | 67 | static void __iomem *hpet_mctr; |
66 | 68 | ||
67 | static cycle_t read_hpet(void) | 69 | static cycle_t read_hpet(void) |
@@ -79,6 +81,7 @@ static struct clocksource clocksource_hpet = { | |||
79 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 81 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
80 | }; | 82 | }; |
81 | static struct clocksource *hpet_clocksource; | 83 | static struct clocksource *hpet_clocksource; |
84 | #endif | ||
82 | 85 | ||
83 | /* A lock for concurrent access by app and isr hpet activity. */ | 86 | /* A lock for concurrent access by app and isr hpet activity. */ |
84 | static DEFINE_SPINLOCK(hpet_lock); | 87 | static DEFINE_SPINLOCK(hpet_lock); |
@@ -909,6 +912,8 @@ int hpet_alloc(struct hpet_data *hdp) | |||
909 | 912 | ||
910 | hpetp->hp_delta = hpet_calibrate(hpetp); | 913 | hpetp->hp_delta = hpet_calibrate(hpetp); |
911 | 914 | ||
915 | /* This clocksource driver currently only works on ia64 */ | ||
916 | #ifdef CONFIG_IA64 | ||
912 | if (!hpet_clocksource) { | 917 | if (!hpet_clocksource) { |
913 | hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc; | 918 | hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc; |
914 | CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr); | 919 | CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr); |
@@ -918,6 +923,7 @@ int hpet_alloc(struct hpet_data *hdp) | |||
918 | hpetp->hp_clocksource = &clocksource_hpet; | 923 | hpetp->hp_clocksource = &clocksource_hpet; |
919 | hpet_clocksource = &clocksource_hpet; | 924 | hpet_clocksource = &clocksource_hpet; |
920 | } | 925 | } |
926 | #endif | ||
921 | 927 | ||
922 | return 0; | 928 | return 0; |
923 | } | 929 | } |
@@ -940,14 +946,14 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
940 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", | 946 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", |
941 | __FUNCTION__, hdp->hd_phys_address); | 947 | __FUNCTION__, hdp->hd_phys_address); |
942 | iounmap(hdp->hd_address); | 948 | iounmap(hdp->hd_address); |
943 | return -EBUSY; | 949 | return AE_ALREADY_EXISTS; |
944 | } | 950 | } |
945 | } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) { | 951 | } else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) { |
946 | struct acpi_resource_fixed_memory32 *fixmem32; | 952 | struct acpi_resource_fixed_memory32 *fixmem32; |
947 | 953 | ||
948 | fixmem32 = &res->data.fixed_memory32; | 954 | fixmem32 = &res->data.fixed_memory32; |
949 | if (!fixmem32) | 955 | if (!fixmem32) |
950 | return -EINVAL; | 956 | return AE_NO_MEMORY; |
951 | 957 | ||
952 | hdp->hd_phys_address = fixmem32->address; | 958 | hdp->hd_phys_address = fixmem32->address; |
953 | hdp->hd_address = ioremap(fixmem32->address, | 959 | hdp->hd_address = ioremap(fixmem32->address, |
@@ -957,7 +963,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
957 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", | 963 | printk(KERN_DEBUG "%s: 0x%lx is busy\n", |
958 | __FUNCTION__, hdp->hd_phys_address); | 964 | __FUNCTION__, hdp->hd_phys_address); |
959 | iounmap(hdp->hd_address); | 965 | iounmap(hdp->hd_address); |
960 | return -EBUSY; | 966 | return AE_ALREADY_EXISTS; |
961 | } | 967 | } |
962 | } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { | 968 | } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { |
963 | struct acpi_resource_extended_irq *irqp; | 969 | 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 9b07f7851061..dd441ff4af56 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) | |||
2215 | 2215 | ||
2216 | static struct pci_device_id ipmi_pci_devices[] = { | 2216 | static struct pci_device_id ipmi_pci_devices[] = { |
2217 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, | 2217 | { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, |
2218 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) } | 2218 | { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }, |
2219 | { 0, } | ||
2219 | }; | 2220 | }; |
2220 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); | 2221 | MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); |
2221 | 2222 | ||
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 1f0962616ee5..4fe9206f84de 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <asm/io.h> | 25 | #include <asm/io.h> |
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | #include <asm/system.h> | 27 | #include <asm/system.h> |
28 | #include <linux/delay.h> | ||
29 | 28 | ||
30 | #include "lcd.h" | 29 | #include "lcd.h" |
31 | 30 | ||
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index c08a4152ee8f..04ac155d3a07 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c | |||
@@ -67,7 +67,7 @@ | |||
67 | /* | 67 | /* |
68 | * Page types allocated by the device. | 68 | * Page types allocated by the device. |
69 | */ | 69 | */ |
70 | enum { | 70 | enum mspec_page_type { |
71 | MSPEC_FETCHOP = 1, | 71 | MSPEC_FETCHOP = 1, |
72 | MSPEC_CACHED, | 72 | MSPEC_CACHED, |
73 | MSPEC_UNCACHED | 73 | MSPEC_UNCACHED |
@@ -83,15 +83,25 @@ static int is_sn2; | |||
83 | * One of these structures is allocated when an mspec region is mmaped. The | 83 | * One of these structures is allocated when an mspec region is mmaped. The |
84 | * structure is pointed to by the vma->vm_private_data field in the vma struct. | 84 | * structure is pointed to by the vma->vm_private_data field in the vma struct. |
85 | * This structure is used to record the addresses of the mspec pages. | 85 | * This structure is used to record the addresses of the mspec pages. |
86 | * This structure is shared by all vma's that are split off from the | ||
87 | * original vma when split_vma()'s are done. | ||
88 | * | ||
89 | * The refcnt is incremented atomically because mm->mmap_sem does not | ||
90 | * protect in fork case where multiple tasks share the vma_data. | ||
86 | */ | 91 | */ |
87 | struct vma_data { | 92 | struct vma_data { |
88 | atomic_t refcnt; /* Number of vmas sharing the data. */ | 93 | atomic_t refcnt; /* Number of vmas sharing the data. */ |
89 | spinlock_t lock; /* Serialize access to the vma. */ | 94 | spinlock_t lock; /* Serialize access to this structure. */ |
90 | int count; /* Number of pages allocated. */ | 95 | int count; /* Number of pages allocated. */ |
91 | int type; /* Type of pages allocated. */ | 96 | enum mspec_page_type type; /* Type of pages allocated. */ |
97 | int flags; /* See VMD_xxx below. */ | ||
98 | unsigned long vm_start; /* Original (unsplit) base. */ | ||
99 | unsigned long vm_end; /* Original (unsplit) end. */ | ||
92 | unsigned long maddr[0]; /* Array of MSPEC addresses. */ | 100 | unsigned long maddr[0]; /* Array of MSPEC addresses. */ |
93 | }; | 101 | }; |
94 | 102 | ||
103 | #define VMD_VMALLOCED 0x1 /* vmalloc'd rather than kmalloc'd */ | ||
104 | |||
95 | /* used on shub2 to clear FOP cache in the HUB */ | 105 | /* used on shub2 to clear FOP cache in the HUB */ |
96 | static unsigned long scratch_page[MAX_NUMNODES]; | 106 | static unsigned long scratch_page[MAX_NUMNODES]; |
97 | #define SH2_AMO_CACHE_ENTRIES 4 | 107 | #define SH2_AMO_CACHE_ENTRIES 4 |
@@ -129,8 +139,8 @@ mspec_zero_block(unsigned long addr, int len) | |||
129 | * mspec_open | 139 | * mspec_open |
130 | * | 140 | * |
131 | * Called when a device mapping is created by a means other than mmap | 141 | * Called when a device mapping is created by a means other than mmap |
132 | * (via fork, etc.). Increments the reference count on the underlying | 142 | * (via fork, munmap, etc.). Increments the reference count on the |
133 | * mspec data so it is not freed prematurely. | 143 | * underlying mspec data so it is not freed prematurely. |
134 | */ | 144 | */ |
135 | static void | 145 | static void |
136 | mspec_open(struct vm_area_struct *vma) | 146 | mspec_open(struct vm_area_struct *vma) |
@@ -145,43 +155,43 @@ mspec_open(struct vm_area_struct *vma) | |||
145 | * mspec_close | 155 | * mspec_close |
146 | * | 156 | * |
147 | * Called when unmapping a device mapping. Frees all mspec pages | 157 | * Called when unmapping a device mapping. Frees all mspec pages |
148 | * belonging to the vma. | 158 | * belonging to all the vma's sharing this vma_data structure. |
149 | */ | 159 | */ |
150 | static void | 160 | static void |
151 | mspec_close(struct vm_area_struct *vma) | 161 | mspec_close(struct vm_area_struct *vma) |
152 | { | 162 | { |
153 | struct vma_data *vdata; | 163 | struct vma_data *vdata; |
154 | int i, pages, result, vdata_size; | 164 | int index, last_index; |
165 | unsigned long my_page; | ||
155 | 166 | ||
156 | vdata = vma->vm_private_data; | 167 | vdata = vma->vm_private_data; |
168 | |||
157 | if (!atomic_dec_and_test(&vdata->refcnt)) | 169 | if (!atomic_dec_and_test(&vdata->refcnt)) |
158 | return; | 170 | return; |
159 | 171 | ||
160 | pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 172 | last_index = (vdata->vm_end - vdata->vm_start) >> PAGE_SHIFT; |
161 | vdata_size = sizeof(struct vma_data) + pages * sizeof(long); | 173 | for (index = 0; index < last_index; index++) { |
162 | for (i = 0; i < pages; i++) { | 174 | if (vdata->maddr[index] == 0) |
163 | if (vdata->maddr[i] == 0) | ||
164 | continue; | 175 | continue; |
165 | /* | 176 | /* |
166 | * Clear the page before sticking it back | 177 | * Clear the page before sticking it back |
167 | * into the pool. | 178 | * into the pool. |
168 | */ | 179 | */ |
169 | result = mspec_zero_block(vdata->maddr[i], PAGE_SIZE); | 180 | my_page = vdata->maddr[index]; |
170 | if (!result) | 181 | vdata->maddr[index] = 0; |
171 | uncached_free_page(vdata->maddr[i]); | 182 | if (!mspec_zero_block(my_page, PAGE_SIZE)) |
183 | uncached_free_page(my_page); | ||
172 | else | 184 | else |
173 | printk(KERN_WARNING "mspec_close(): " | 185 | printk(KERN_WARNING "mspec_close(): " |
174 | "failed to zero page %i\n", | 186 | "failed to zero page %ld\n", my_page); |
175 | result); | ||
176 | } | 187 | } |
177 | 188 | ||
178 | if (vdata_size <= PAGE_SIZE) | 189 | if (vdata->flags & VMD_VMALLOCED) |
179 | kfree(vdata); | ||
180 | else | ||
181 | vfree(vdata); | 190 | vfree(vdata); |
191 | else | ||
192 | kfree(vdata); | ||
182 | } | 193 | } |
183 | 194 | ||
184 | |||
185 | /* | 195 | /* |
186 | * mspec_nopfn | 196 | * mspec_nopfn |
187 | * | 197 | * |
@@ -195,7 +205,8 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) | |||
195 | int index; | 205 | int index; |
196 | struct vma_data *vdata = vma->vm_private_data; | 206 | struct vma_data *vdata = vma->vm_private_data; |
197 | 207 | ||
198 | index = (address - vma->vm_start) >> PAGE_SHIFT; | 208 | BUG_ON(address < vdata->vm_start || address >= vdata->vm_end); |
209 | index = (address - vdata->vm_start) >> PAGE_SHIFT; | ||
199 | maddr = (volatile unsigned long) vdata->maddr[index]; | 210 | maddr = (volatile unsigned long) vdata->maddr[index]; |
200 | if (maddr == 0) { | 211 | if (maddr == 0) { |
201 | maddr = uncached_alloc_page(numa_node_id()); | 212 | maddr = uncached_alloc_page(numa_node_id()); |
@@ -237,10 +248,11 @@ static struct vm_operations_struct mspec_vm_ops = { | |||
237 | * underlying pages. | 248 | * underlying pages. |
238 | */ | 249 | */ |
239 | static int | 250 | static int |
240 | mspec_mmap(struct file *file, struct vm_area_struct *vma, int type) | 251 | mspec_mmap(struct file *file, struct vm_area_struct *vma, |
252 | enum mspec_page_type type) | ||
241 | { | 253 | { |
242 | struct vma_data *vdata; | 254 | struct vma_data *vdata; |
243 | int pages, vdata_size; | 255 | int pages, vdata_size, flags = 0; |
244 | 256 | ||
245 | if (vma->vm_pgoff != 0) | 257 | if (vma->vm_pgoff != 0) |
246 | return -EINVAL; | 258 | return -EINVAL; |
@@ -255,12 +267,17 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, int type) | |||
255 | vdata_size = sizeof(struct vma_data) + pages * sizeof(long); | 267 | vdata_size = sizeof(struct vma_data) + pages * sizeof(long); |
256 | if (vdata_size <= PAGE_SIZE) | 268 | if (vdata_size <= PAGE_SIZE) |
257 | vdata = kmalloc(vdata_size, GFP_KERNEL); | 269 | vdata = kmalloc(vdata_size, GFP_KERNEL); |
258 | else | 270 | else { |
259 | vdata = vmalloc(vdata_size); | 271 | vdata = vmalloc(vdata_size); |
272 | flags = VMD_VMALLOCED; | ||
273 | } | ||
260 | if (!vdata) | 274 | if (!vdata) |
261 | return -ENOMEM; | 275 | return -ENOMEM; |
262 | memset(vdata, 0, vdata_size); | 276 | memset(vdata, 0, vdata_size); |
263 | 277 | ||
278 | vdata->vm_start = vma->vm_start; | ||
279 | vdata->vm_end = vma->vm_end; | ||
280 | vdata->flags = flags; | ||
264 | vdata->type = type; | 281 | vdata->type = type; |
265 | spin_lock_init(&vdata->lock); | 282 | spin_lock_init(&vdata->lock); |
266 | vdata->refcnt = ATOMIC_INIT(1); | 283 | vdata->refcnt = ATOMIC_INIT(1); |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 397c714cf2ba..af274e5a25ee 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1550,11 +1550,13 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, | |||
1550 | * As close as possible to RFC 793, which | 1550 | * As close as possible to RFC 793, which |
1551 | * suggests using a 250 kHz clock. | 1551 | * suggests using a 250 kHz clock. |
1552 | * Further reading shows this assumes 2 Mb/s networks. | 1552 | * Further reading shows this assumes 2 Mb/s networks. |
1553 | * For 10 Gb/s Ethernet, a 1 GHz clock is appropriate. | 1553 | * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. |
1554 | * That's funny, Linux has one built in! Use it! | 1554 | * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but |
1555 | * (Networks are faster now - should this be increased?) | 1555 | * we also need to limit the resolution so that the u32 seq |
1556 | * overlaps less than one time per MSL (2 minutes). | ||
1557 | * Choosing a clock of 64 ns period is OK. (period of 274 s) | ||
1556 | */ | 1558 | */ |
1557 | seq += ktime_get_real().tv64; | 1559 | seq += ktime_get_real().tv64 >> 6; |
1558 | #if 0 | 1560 | #if 0 |
1559 | printk("init_seq(%lx, %lx, %d, %d) = %d\n", | 1561 | printk("init_seq(%lx, %lx, %d, %d) = %d\n", |
1560 | saddr, daddr, sport, dport, seq); | 1562 | saddr, daddr, sport, dport, seq); |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index aeec67e27264..859858561ab6 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -875,7 +875,7 @@ found: | |||
875 | 875 | ||
876 | #ifdef CONFIG_ACPI | 876 | #ifdef CONFIG_ACPI |
877 | if (sonypi_acpi_device) | 877 | if (sonypi_acpi_device) |
878 | acpi_bus_generate_event(sonypi_acpi_device, 1, event); | 878 | acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); |
879 | #endif | 879 | #endif |
880 | 880 | ||
881 | kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); | 881 | 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 51ea93cab6c4..9c867cf6de64 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, | |||
2063 | } | 2063 | } |
2064 | 2064 | ||
2065 | if (!*tp_loc) { | 2065 | if (!*tp_loc) { |
2066 | tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), | 2066 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
2067 | GFP_KERNEL); | ||
2068 | if (!tp) | 2067 | if (!tp) |
2069 | goto free_mem_out; | 2068 | goto free_mem_out; |
2070 | *tp = driver->init_termios; | 2069 | *tp = driver->init_termios; |
@@ -2094,8 +2093,7 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
2094 | } | 2093 | } |
2095 | 2094 | ||
2096 | if (!*o_tp_loc) { | 2095 | if (!*o_tp_loc) { |
2097 | o_tp = (struct ktermios *) | 2096 | o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
2098 | kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
2099 | if (!o_tp) | 2097 | if (!o_tp) |
2100 | goto free_mem_out; | 2098 | goto free_mem_out; |
2101 | *o_tp = driver->other->init_termios; | 2099 | *o_tp = driver->other->init_termios; |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 3423e9ee6481..3ee73cf64bd2 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, | |||
795 | if (L_ICANON(tty)) | 795 | if (L_ICANON(tty)) |
796 | retval = inq_canon(tty); | 796 | retval = inq_canon(tty); |
797 | return put_user(retval, (unsigned int __user *) arg); | 797 | return put_user(retval, (unsigned int __user *) arg); |
798 | #ifndef TCGETS2 | ||
798 | case TIOCGLCKTRMIOS: | 799 | case TIOCGLCKTRMIOS: |
799 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) | 800 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked)) |
800 | return -EFAULT; | 801 | return -EFAULT; |
@@ -806,6 +807,19 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, | |||
806 | if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg)) | 807 | if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg)) |
807 | return -EFAULT; | 808 | return -EFAULT; |
808 | return 0; | 809 | return 0; |
810 | #else | ||
811 | case TIOCGLCKTRMIOS: | ||
812 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked)) | ||
813 | return -EFAULT; | ||
814 | return 0; | ||
815 | |||
816 | case TIOCSLCKTRMIOS: | ||
817 | if (!capable(CAP_SYS_ADMIN)) | ||
818 | return -EPERM; | ||
819 | if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg)) | ||
820 | return -EFAULT; | ||
821 | return 0; | ||
822 | #endif | ||
809 | 823 | ||
810 | case TIOCPKT: | 824 | case TIOCPKT: |
811 | { | 825 | { |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index c6f6f4209739..7a61a2a9aafe 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, | |||
770 | /* | 770 | /* |
771 | * Switching-from response | 771 | * Switching-from response |
772 | */ | 772 | */ |
773 | acquire_console_sem(); | ||
773 | if (vc->vt_newvt >= 0) { | 774 | if (vc->vt_newvt >= 0) { |
774 | if (arg == 0) | 775 | if (arg == 0) |
775 | /* | 776 | /* |
@@ -784,7 +785,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
784 | * complete the switch. | 785 | * complete the switch. |
785 | */ | 786 | */ |
786 | int newvt; | 787 | int newvt; |
787 | acquire_console_sem(); | ||
788 | newvt = vc->vt_newvt; | 788 | newvt = vc->vt_newvt; |
789 | vc->vt_newvt = -1; | 789 | vc->vt_newvt = -1; |
790 | i = vc_allocate(newvt); | 790 | i = vc_allocate(newvt); |
@@ -798,7 +798,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
798 | * other console switches.. | 798 | * other console switches.. |
799 | */ | 799 | */ |
800 | complete_change_console(vc_cons[newvt].d); | 800 | complete_change_console(vc_cons[newvt].d); |
801 | release_console_sem(); | ||
802 | } | 801 | } |
803 | } | 802 | } |
804 | 803 | ||
@@ -810,9 +809,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
810 | /* | 809 | /* |
811 | * If it's just an ACK, ignore it | 810 | * If it's just an ACK, ignore it |
812 | */ | 811 | */ |
813 | if (arg != VT_ACKACQ) | 812 | if (arg != VT_ACKACQ) { |
813 | release_console_sem(); | ||
814 | return -EINVAL; | 814 | return -EINVAL; |
815 | } | ||
815 | } | 816 | } |
817 | release_console_sem(); | ||
816 | 818 | ||
817 | return 0; | 819 | return 0; |
818 | 820 | ||
@@ -1030,7 +1032,7 @@ static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue); | |||
1030 | 1032 | ||
1031 | /* | 1033 | /* |
1032 | * Sleeps until a vt is activated, or the task is interrupted. Returns | 1034 | * Sleeps until a vt is activated, or the task is interrupted. Returns |
1033 | * 0 if activation, -EINTR if interrupted. | 1035 | * 0 if activation, -EINTR if interrupted by a signal handler. |
1034 | */ | 1036 | */ |
1035 | int vt_waitactive(int vt) | 1037 | int vt_waitactive(int vt) |
1036 | { | 1038 | { |
@@ -1055,7 +1057,7 @@ int vt_waitactive(int vt) | |||
1055 | break; | 1057 | break; |
1056 | } | 1058 | } |
1057 | release_console_sem(); | 1059 | release_console_sem(); |
1058 | retval = -EINTR; | 1060 | retval = -ERESTARTNOHAND; |
1059 | if (signal_pending(current)) | 1061 | if (signal_pending(current)) |
1060 | break; | 1062 | break; |
1061 | schedule(); | 1063 | schedule(); |
@@ -1208,15 +1210,18 @@ void change_console(struct vc_data *new_vc) | |||
1208 | /* | 1210 | /* |
1209 | * Send the signal as privileged - kill_pid() will | 1211 | * Send the signal as privileged - kill_pid() will |
1210 | * tell us if the process has gone or something else | 1212 | * tell us if the process has gone or something else |
1211 | * is awry | 1213 | * is awry. |
1214 | * | ||
1215 | * We need to set vt_newvt *before* sending the signal or we | ||
1216 | * have a race. | ||
1212 | */ | 1217 | */ |
1218 | vc->vt_newvt = new_vc->vc_num; | ||
1213 | if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { | 1219 | if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { |
1214 | /* | 1220 | /* |
1215 | * It worked. Mark the vt to switch to and | 1221 | * It worked. Mark the vt to switch to and |
1216 | * return. The process needs to send us a | 1222 | * return. The process needs to send us a |
1217 | * VT_RELDISP ioctl to complete the switch. | 1223 | * VT_RELDISP ioctl to complete the switch. |
1218 | */ | 1224 | */ |
1219 | vc->vt_newvt = new_vc->vc_num; | ||
1220 | return; | 1225 | return; |
1221 | } | 1226 | } |
1222 | 1227 | ||