diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/agp/intel-agp.c | 28 | ||||
-rw-r--r-- | drivers/char/agp/intel-gtt.c | 63 | ||||
-rw-r--r-- | drivers/char/hpet.c | 17 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 42 | ||||
-rw-r--r-- | drivers/char/n_gsm.c | 6 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 2 | ||||
-rw-r--r-- | drivers/char/ramoops.c | 12 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.c | 28 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 28 | ||||
-rw-r--r-- | drivers/char/tty_buffer.c | 14 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 13 | ||||
-rw-r--r-- | drivers/char/tty_ldisc.c | 51 | ||||
-rw-r--r-- | drivers/char/virtio_console.c | 15 | ||||
-rw-r--r-- | drivers/char/vt_ioctl.c | 11 |
15 files changed, 232 insertions, 100 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index cd18493c9527..aa5c782bf015 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -927,20 +927,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
927 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); | 927 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); |
928 | 928 | ||
929 | /* | 929 | /* |
930 | * If the device has not been properly setup, the following will catch | ||
931 | * the problem and should stop the system from crashing. | ||
932 | * 20030610 - hamish@zot.org | ||
933 | */ | ||
934 | if (pci_enable_device(pdev)) { | ||
935 | dev_err(&pdev->dev, "can't enable PCI device\n"); | ||
936 | agp_put_bridge(bridge); | ||
937 | return -ENODEV; | ||
938 | } | ||
939 | |||
940 | /* | ||
941 | * The following fixes the case where the BIOS has "forgotten" to | 930 | * The following fixes the case where the BIOS has "forgotten" to |
942 | * provide an address range for the GART. | 931 | * provide an address range for the GART. |
943 | * 20030610 - hamish@zot.org | 932 | * 20030610 - hamish@zot.org |
933 | * This happens before pci_enable_device() intentionally; | ||
934 | * calling pci_enable_device() before assigning the resource | ||
935 | * will result in the GART being disabled on machines with such | ||
936 | * BIOSs (the GART ends up with a BAR starting at 0, which | ||
937 | * conflicts a lot of other devices). | ||
944 | */ | 938 | */ |
945 | r = &pdev->resource[0]; | 939 | r = &pdev->resource[0]; |
946 | if (!r->start && r->end) { | 940 | if (!r->start && r->end) { |
@@ -951,6 +945,17 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
951 | } | 945 | } |
952 | } | 946 | } |
953 | 947 | ||
948 | /* | ||
949 | * If the device has not been properly setup, the following will catch | ||
950 | * the problem and should stop the system from crashing. | ||
951 | * 20030610 - hamish@zot.org | ||
952 | */ | ||
953 | if (pci_enable_device(pdev)) { | ||
954 | dev_err(&pdev->dev, "can't enable PCI device\n"); | ||
955 | agp_put_bridge(bridge); | ||
956 | return -ENODEV; | ||
957 | } | ||
958 | |||
954 | /* Fill in the mode register */ | 959 | /* Fill in the mode register */ |
955 | if (cap_ptr) { | 960 | if (cap_ptr) { |
956 | pci_read_config_dword(pdev, | 961 | pci_read_config_dword(pdev, |
@@ -1049,6 +1054,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
1049 | ID(PCI_DEVICE_ID_INTEL_G45_HB), | 1054 | ID(PCI_DEVICE_ID_INTEL_G45_HB), |
1050 | ID(PCI_DEVICE_ID_INTEL_G41_HB), | 1055 | ID(PCI_DEVICE_ID_INTEL_G41_HB), |
1051 | ID(PCI_DEVICE_ID_INTEL_B43_HB), | 1056 | ID(PCI_DEVICE_ID_INTEL_B43_HB), |
1057 | ID(PCI_DEVICE_ID_INTEL_B43_1_HB), | ||
1052 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), | 1058 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), |
1053 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), | 1059 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), |
1054 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), | 1060 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 75e0a3497888..6ea3bf6e5b1a 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -534,7 +534,7 @@ static void intel_i830_init_gtt_entries(void) | |||
534 | 534 | ||
535 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | 535 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); |
536 | 536 | ||
537 | if (IS_I965) { | 537 | if (IS_G33 || IS_I965) { |
538 | u32 pgetbl_ctl; | 538 | u32 pgetbl_ctl; |
539 | pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); | 539 | pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); |
540 | 540 | ||
@@ -567,22 +567,6 @@ static void intel_i830_init_gtt_entries(void) | |||
567 | size = 512; | 567 | size = 512; |
568 | } | 568 | } |
569 | size += 4; /* add in BIOS popup space */ | 569 | size += 4; /* add in BIOS popup space */ |
570 | } else if (IS_G33 && !IS_PINEVIEW) { | ||
571 | /* G33's GTT size defined in gmch_ctrl */ | ||
572 | switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { | ||
573 | case G33_PGETBL_SIZE_1M: | ||
574 | size = 1024; | ||
575 | break; | ||
576 | case G33_PGETBL_SIZE_2M: | ||
577 | size = 2048; | ||
578 | break; | ||
579 | default: | ||
580 | dev_info(&agp_bridge->dev->dev, | ||
581 | "unknown page table size 0x%x, assuming 512KB\n", | ||
582 | (gmch_ctrl & G33_PGETBL_SIZE_MASK)); | ||
583 | size = 512; | ||
584 | } | ||
585 | size += 4; | ||
586 | } else if (IS_G4X || IS_PINEVIEW) { | 570 | } else if (IS_G4X || IS_PINEVIEW) { |
587 | /* On 4 series hardware, GTT stolen is separate from graphics | 571 | /* On 4 series hardware, GTT stolen is separate from graphics |
588 | * stolen, ignore it in stolen gtt entries counting. However, | 572 | * stolen, ignore it in stolen gtt entries counting. However, |
@@ -1257,24 +1241,31 @@ static int intel_i915_get_gtt_size(void) | |||
1257 | int size; | 1241 | int size; |
1258 | 1242 | ||
1259 | if (IS_G33) { | 1243 | if (IS_G33) { |
1260 | u16 gmch_ctrl; | 1244 | u32 pgetbl_ctl; |
1245 | pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); | ||
1261 | 1246 | ||
1262 | /* G33's GTT size defined in gmch_ctrl */ | 1247 | switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) { |
1263 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | 1248 | case I965_PGETBL_SIZE_128KB: |
1264 | switch (gmch_ctrl & I830_GMCH_GMS_MASK) { | 1249 | size = 128; |
1265 | case I830_GMCH_GMS_STOLEN_512: | 1250 | break; |
1251 | case I965_PGETBL_SIZE_256KB: | ||
1252 | size = 256; | ||
1253 | break; | ||
1254 | case I965_PGETBL_SIZE_512KB: | ||
1266 | size = 512; | 1255 | size = 512; |
1267 | break; | 1256 | break; |
1268 | case I830_GMCH_GMS_STOLEN_1024: | 1257 | case I965_PGETBL_SIZE_1MB: |
1269 | size = 1024; | 1258 | size = 1024; |
1270 | break; | 1259 | break; |
1271 | case I830_GMCH_GMS_STOLEN_8192: | 1260 | case I965_PGETBL_SIZE_2MB: |
1272 | size = 8*1024; | 1261 | size = 2048; |
1262 | break; | ||
1263 | case I965_PGETBL_SIZE_1_5MB: | ||
1264 | size = 1024 + 512; | ||
1273 | break; | 1265 | break; |
1274 | default: | 1266 | default: |
1275 | dev_info(&agp_bridge->dev->dev, | 1267 | dev_info(&intel_private.pcidev->dev, |
1276 | "unknown page table size 0x%x, assuming 512KB\n", | 1268 | "unknown page table size, assuming 512KB\n"); |
1277 | (gmch_ctrl & I830_GMCH_GMS_MASK)); | ||
1278 | size = 512; | 1269 | size = 512; |
1279 | } | 1270 | } |
1280 | } else { | 1271 | } else { |
@@ -1306,14 +1297,6 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
1306 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | 1297 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); |
1307 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); | 1298 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); |
1308 | 1299 | ||
1309 | gtt_map_size = intel_i915_get_gtt_size(); | ||
1310 | |||
1311 | intel_private.gtt = ioremap(temp2, gtt_map_size); | ||
1312 | if (!intel_private.gtt) | ||
1313 | return -ENOMEM; | ||
1314 | |||
1315 | intel_private.gtt_total_size = gtt_map_size / 4; | ||
1316 | |||
1317 | temp &= 0xfff80000; | 1300 | temp &= 0xfff80000; |
1318 | 1301 | ||
1319 | intel_private.registers = ioremap(temp, 128 * 4096); | 1302 | intel_private.registers = ioremap(temp, 128 * 4096); |
@@ -1322,6 +1305,14 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
1322 | return -ENOMEM; | 1305 | return -ENOMEM; |
1323 | } | 1306 | } |
1324 | 1307 | ||
1308 | gtt_map_size = intel_i915_get_gtt_size(); | ||
1309 | |||
1310 | intel_private.gtt = ioremap(temp2, gtt_map_size); | ||
1311 | if (!intel_private.gtt) | ||
1312 | return -ENOMEM; | ||
1313 | |||
1314 | intel_private.gtt_total_size = gtt_map_size / 4; | ||
1315 | |||
1325 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | 1316 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; |
1326 | global_cache_flush(); /* FIXME: ? */ | 1317 | global_cache_flush(); /* FIXME: ? */ |
1327 | 1318 | ||
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index a0a1829d3198..f8e7d89ceb2c 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -479,6 +479,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
479 | if (irq) { | 479 | if (irq) { |
480 | unsigned long irq_flags; | 480 | unsigned long irq_flags; |
481 | 481 | ||
482 | if (devp->hd_flags & HPET_SHARED_IRQ) { | ||
483 | /* | ||
484 | * To prevent the interrupt handler from seeing an | ||
485 | * unwanted interrupt status bit, program the timer | ||
486 | * so that it will not fire in the near future ... | ||
487 | */ | ||
488 | writel(readl(&timer->hpet_config) & ~Tn_TYPE_CNF_MASK, | ||
489 | &timer->hpet_config); | ||
490 | write_counter(read_counter(&hpet->hpet_mc), | ||
491 | &timer->hpet_compare); | ||
492 | /* ... and clear any left-over status. */ | ||
493 | isr = 1 << (devp - devp->hd_hpets->hp_dev); | ||
494 | writel(isr, &hpet->hpet_isr); | ||
495 | } | ||
496 | |||
482 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); | 497 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); |
483 | irq_flags = devp->hd_flags & HPET_SHARED_IRQ | 498 | irq_flags = devp->hd_flags & HPET_SHARED_IRQ |
484 | ? IRQF_SHARED : IRQF_DISABLED; | 499 | ? IRQF_SHARED : IRQF_DISABLED; |
@@ -970,6 +985,8 @@ static int hpet_acpi_add(struct acpi_device *device) | |||
970 | return -ENODEV; | 985 | return -ENODEV; |
971 | 986 | ||
972 | if (!data.hd_address || !data.hd_nirqs) { | 987 | if (!data.hd_address || !data.hd_nirqs) { |
988 | if (data.hd_address) | ||
989 | iounmap(data.hd_address); | ||
973 | printk("%s: no address or irqs in _CRS\n", __func__); | 990 | printk("%s: no address or irqs in _CRS\n", __func__); |
974 | return -ENODEV; | 991 | return -ENODEV; |
975 | } | 992 | } |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 7bd7c45b53ef..22abd188fe12 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -320,6 +320,7 @@ static int unload_when_empty = 1; | |||
320 | static int add_smi(struct smi_info *smi); | 320 | static int add_smi(struct smi_info *smi); |
321 | static int try_smi_init(struct smi_info *smi); | 321 | static int try_smi_init(struct smi_info *smi); |
322 | static void cleanup_one_si(struct smi_info *to_clean); | 322 | static void cleanup_one_si(struct smi_info *to_clean); |
323 | static void cleanup_ipmi_si(void); | ||
323 | 324 | ||
324 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); | 325 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); |
325 | static int register_xaction_notifier(struct notifier_block *nb) | 326 | static int register_xaction_notifier(struct notifier_block *nb) |
@@ -1665,6 +1666,17 @@ static int check_hotmod_int_op(const char *curr, const char *option, | |||
1665 | return 0; | 1666 | return 0; |
1666 | } | 1667 | } |
1667 | 1668 | ||
1669 | static struct smi_info *smi_info_alloc(void) | ||
1670 | { | ||
1671 | struct smi_info *info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
1672 | |||
1673 | if (info) { | ||
1674 | spin_lock_init(&info->si_lock); | ||
1675 | spin_lock_init(&info->msg_lock); | ||
1676 | } | ||
1677 | return info; | ||
1678 | } | ||
1679 | |||
1668 | static int hotmod_handler(const char *val, struct kernel_param *kp) | 1680 | static int hotmod_handler(const char *val, struct kernel_param *kp) |
1669 | { | 1681 | { |
1670 | char *str = kstrdup(val, GFP_KERNEL); | 1682 | char *str = kstrdup(val, GFP_KERNEL); |
@@ -1779,7 +1791,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) | |||
1779 | } | 1791 | } |
1780 | 1792 | ||
1781 | if (op == HM_ADD) { | 1793 | if (op == HM_ADD) { |
1782 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 1794 | info = smi_info_alloc(); |
1783 | if (!info) { | 1795 | if (!info) { |
1784 | rv = -ENOMEM; | 1796 | rv = -ENOMEM; |
1785 | goto out; | 1797 | goto out; |
@@ -1844,7 +1856,7 @@ static __devinit void hardcode_find_bmc(void) | |||
1844 | if (!ports[i] && !addrs[i]) | 1856 | if (!ports[i] && !addrs[i]) |
1845 | continue; | 1857 | continue; |
1846 | 1858 | ||
1847 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 1859 | info = smi_info_alloc(); |
1848 | if (!info) | 1860 | if (!info) |
1849 | return; | 1861 | return; |
1850 | 1862 | ||
@@ -2028,7 +2040,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) | |||
2028 | return -ENODEV; | 2040 | return -ENODEV; |
2029 | } | 2041 | } |
2030 | 2042 | ||
2031 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2043 | info = smi_info_alloc(); |
2032 | if (!info) { | 2044 | if (!info) { |
2033 | printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); | 2045 | printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); |
2034 | return -ENOMEM; | 2046 | return -ENOMEM; |
@@ -2138,7 +2150,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2138 | if (!acpi_dev) | 2150 | if (!acpi_dev) |
2139 | return -ENODEV; | 2151 | return -ENODEV; |
2140 | 2152 | ||
2141 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2153 | info = smi_info_alloc(); |
2142 | if (!info) | 2154 | if (!info) |
2143 | return -ENOMEM; | 2155 | return -ENOMEM; |
2144 | 2156 | ||
@@ -2319,7 +2331,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) | |||
2319 | { | 2331 | { |
2320 | struct smi_info *info; | 2332 | struct smi_info *info; |
2321 | 2333 | ||
2322 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2334 | info = smi_info_alloc(); |
2323 | if (!info) { | 2335 | if (!info) { |
2324 | printk(KERN_ERR PFX "Could not allocate SI data\n"); | 2336 | printk(KERN_ERR PFX "Could not allocate SI data\n"); |
2325 | return; | 2337 | return; |
@@ -2426,7 +2438,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2426 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; | 2438 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; |
2427 | struct smi_info *info; | 2439 | struct smi_info *info; |
2428 | 2440 | ||
2429 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2441 | info = smi_info_alloc(); |
2430 | if (!info) | 2442 | if (!info) |
2431 | return -ENOMEM; | 2443 | return -ENOMEM; |
2432 | 2444 | ||
@@ -2567,7 +2579,7 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, | |||
2567 | return -EINVAL; | 2579 | return -EINVAL; |
2568 | } | 2580 | } |
2569 | 2581 | ||
2570 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2582 | info = smi_info_alloc(); |
2571 | 2583 | ||
2572 | if (!info) { | 2584 | if (!info) { |
2573 | dev_err(&dev->dev, | 2585 | dev_err(&dev->dev, |
@@ -3014,7 +3026,7 @@ static __devinit void default_find_bmc(void) | |||
3014 | if (check_legacy_ioport(ipmi_defaults[i].port)) | 3026 | if (check_legacy_ioport(ipmi_defaults[i].port)) |
3015 | continue; | 3027 | continue; |
3016 | #endif | 3028 | #endif |
3017 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 3029 | info = smi_info_alloc(); |
3018 | if (!info) | 3030 | if (!info) |
3019 | return; | 3031 | return; |
3020 | 3032 | ||
@@ -3139,9 +3151,6 @@ static int try_smi_init(struct smi_info *new_smi) | |||
3139 | goto out_err; | 3151 | goto out_err; |
3140 | } | 3152 | } |
3141 | 3153 | ||
3142 | spin_lock_init(&(new_smi->si_lock)); | ||
3143 | spin_lock_init(&(new_smi->msg_lock)); | ||
3144 | |||
3145 | /* Do low-level detection first. */ | 3154 | /* Do low-level detection first. */ |
3146 | if (new_smi->handlers->detect(new_smi->si_sm)) { | 3155 | if (new_smi->handlers->detect(new_smi->si_sm)) { |
3147 | if (new_smi->addr_source) | 3156 | if (new_smi->addr_source) |
@@ -3428,16 +3437,7 @@ static __devinit int init_ipmi_si(void) | |||
3428 | mutex_lock(&smi_infos_lock); | 3437 | mutex_lock(&smi_infos_lock); |
3429 | if (unload_when_empty && list_empty(&smi_infos)) { | 3438 | if (unload_when_empty && list_empty(&smi_infos)) { |
3430 | mutex_unlock(&smi_infos_lock); | 3439 | mutex_unlock(&smi_infos_lock); |
3431 | #ifdef CONFIG_PCI | 3440 | cleanup_ipmi_si(); |
3432 | if (pci_registered) | ||
3433 | pci_unregister_driver(&ipmi_pci_driver); | ||
3434 | #endif | ||
3435 | |||
3436 | #ifdef CONFIG_PPC_OF | ||
3437 | if (of_registered) | ||
3438 | of_unregister_platform_driver(&ipmi_of_platform_driver); | ||
3439 | #endif | ||
3440 | driver_unregister(&ipmi_driver.driver); | ||
3441 | printk(KERN_WARNING PFX | 3441 | printk(KERN_WARNING PFX |
3442 | "Unable to find any System Interface(s)\n"); | 3442 | "Unable to find any System Interface(s)\n"); |
3443 | return -ENODEV; | 3443 | return -ENODEV; |
diff --git a/drivers/char/n_gsm.c b/drivers/char/n_gsm.c index 04ef3ef0a422..0e62674072eb 100644 --- a/drivers/char/n_gsm.c +++ b/drivers/char/n_gsm.c | |||
@@ -716,8 +716,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) | |||
716 | if (msg->len < 128) | 716 | if (msg->len < 128) |
717 | *--dp = (msg->len << 1) | EA; | 717 | *--dp = (msg->len << 1) | EA; |
718 | else { | 718 | else { |
719 | *--dp = (msg->len >> 6) | EA; | 719 | *--dp = (msg->len >> 7); /* bits 7 - 15 */ |
720 | *--dp = (msg->len & 127) << 1; | 720 | *--dp = (msg->len & 127) << 1; /* bits 0 - 6 */ |
721 | } | 721 | } |
722 | } | 722 | } |
723 | 723 | ||
@@ -968,6 +968,8 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data, | |||
968 | { | 968 | { |
969 | struct gsm_msg *msg; | 969 | struct gsm_msg *msg; |
970 | msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype); | 970 | msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype); |
971 | if (msg == NULL) | ||
972 | return; | ||
971 | msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */ | 973 | msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */ |
972 | msg->data[1] = (dlen << 1) | EA; | 974 | msg->data[1] = (dlen << 1) | EA; |
973 | memcpy(msg->data + 2, data, dlen); | 975 | memcpy(msg->data + 2, data, dlen); |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 9ecd6bef5d3b..45f9fad4f5dc 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -4127,6 +4127,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
4127 | if (cmd != SIOCWANDEV) | 4127 | if (cmd != SIOCWANDEV) |
4128 | return hdlc_ioctl(dev, ifr, cmd); | 4128 | return hdlc_ioctl(dev, ifr, cmd); |
4129 | 4129 | ||
4130 | memset(&new_line, 0, size); | ||
4131 | |||
4130 | switch(ifr->ifr_settings.type) { | 4132 | switch(ifr->ifr_settings.type) { |
4131 | case IF_GET_IFACE: /* return current sync_serial_settings */ | 4133 | case IF_GET_IFACE: /* return current sync_serial_settings */ |
4132 | 4134 | ||
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c index 74f00b5ffa36..9445f48c692f 100644 --- a/drivers/char/ramoops.c +++ b/drivers/char/ramoops.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | 28 | ||
29 | #define RAMOOPS_KERNMSG_HDR "====" | 29 | #define RAMOOPS_KERNMSG_HDR "====" |
30 | #define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) | ||
31 | 30 | ||
32 | #define RECORD_SIZE 4096 | 31 | #define RECORD_SIZE 4096 |
33 | 32 | ||
@@ -63,8 +62,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
63 | struct ramoops_context, dump); | 62 | struct ramoops_context, dump); |
64 | unsigned long s1_start, s2_start; | 63 | unsigned long s1_start, s2_start; |
65 | unsigned long l1_cpy, l2_cpy; | 64 | unsigned long l1_cpy, l2_cpy; |
66 | int res; | 65 | int res, hdr_size; |
67 | char *buf; | 66 | char *buf, *buf_orig; |
68 | struct timeval timestamp; | 67 | struct timeval timestamp; |
69 | 68 | ||
70 | /* Only dump oopses if dump_oops is set */ | 69 | /* Only dump oopses if dump_oops is set */ |
@@ -72,6 +71,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
72 | return; | 71 | return; |
73 | 72 | ||
74 | buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE)); | 73 | buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE)); |
74 | buf_orig = buf; | ||
75 | |||
75 | memset(buf, '\0', RECORD_SIZE); | 76 | memset(buf, '\0', RECORD_SIZE); |
76 | res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR); | 77 | res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR); |
77 | buf += res; | 78 | buf += res; |
@@ -79,8 +80,9 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
79 | res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec); | 80 | res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec); |
80 | buf += res; | 81 | buf += res; |
81 | 82 | ||
82 | l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE)); | 83 | hdr_size = buf - buf_orig; |
83 | l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE) - l2_cpy); | 84 | l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - hdr_size)); |
85 | l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - hdr_size) - l2_cpy); | ||
84 | 86 | ||
85 | s2_start = l2 - l2_cpy; | 87 | s2_start = l2 - l2_cpy; |
86 | s1_start = l1 - l1_cpy; | 88 | s1_start = l1 - l1_cpy; |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 05ad4a17a28f..2ec5f33cdbd0 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -354,12 +354,14 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, | |||
354 | tpm_protected_ordinal_duration[ordinal & | 354 | tpm_protected_ordinal_duration[ordinal & |
355 | TPM_PROTECTED_ORDINAL_MASK]; | 355 | TPM_PROTECTED_ORDINAL_MASK]; |
356 | 356 | ||
357 | if (duration_idx != TPM_UNDEFINED) | 357 | if (duration_idx != TPM_UNDEFINED) { |
358 | duration = chip->vendor.duration[duration_idx]; | 358 | duration = chip->vendor.duration[duration_idx]; |
359 | if (duration <= 0) | 359 | /* if duration is 0, it's because chip->vendor.duration wasn't */ |
360 | /* filled yet, so we set the lowest timeout just to give enough */ | ||
361 | /* time for tpm_get_timeouts() to succeed */ | ||
362 | return (duration <= 0 ? HZ : duration); | ||
363 | } else | ||
360 | return 2 * 60 * HZ; | 364 | return 2 * 60 * HZ; |
361 | else | ||
362 | return duration; | ||
363 | } | 365 | } |
364 | EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); | 366 | EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); |
365 | 367 | ||
@@ -565,9 +567,11 @@ duration: | |||
565 | if (rc) | 567 | if (rc) |
566 | return; | 568 | return; |
567 | 569 | ||
568 | if (be32_to_cpu(tpm_cmd.header.out.return_code) | 570 | if (be32_to_cpu(tpm_cmd.header.out.return_code) != 0 || |
569 | != 3 * sizeof(u32)) | 571 | be32_to_cpu(tpm_cmd.header.out.length) |
572 | != sizeof(tpm_cmd.header.out) + sizeof(u32) + 3 * sizeof(u32)) | ||
570 | return; | 573 | return; |
574 | |||
571 | duration_cap = &tpm_cmd.params.getcap_out.cap.duration; | 575 | duration_cap = &tpm_cmd.params.getcap_out.cap.duration; |
572 | chip->vendor.duration[TPM_SHORT] = | 576 | chip->vendor.duration[TPM_SHORT] = |
573 | usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short)); | 577 | usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short)); |
@@ -911,6 +915,18 @@ ssize_t tpm_show_caps_1_2(struct device * dev, | |||
911 | } | 915 | } |
912 | EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); | 916 | EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); |
913 | 917 | ||
918 | ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr, | ||
919 | char *buf) | ||
920 | { | ||
921 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
922 | |||
923 | return sprintf(buf, "%d %d %d\n", | ||
924 | jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]), | ||
925 | jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]), | ||
926 | jiffies_to_usecs(chip->vendor.duration[TPM_LONG])); | ||
927 | } | ||
928 | EXPORT_SYMBOL_GPL(tpm_show_timeouts); | ||
929 | |||
914 | ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, | 930 | ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, |
915 | const char *buf, size_t count) | 931 | const char *buf, size_t count) |
916 | { | 932 | { |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 792868d24f2a..ba1779c2cffd 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -56,6 +56,8 @@ extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr, | |||
56 | char *); | 56 | char *); |
57 | extern ssize_t tpm_show_temp_deactivated(struct device *, | 57 | extern ssize_t tpm_show_temp_deactivated(struct device *, |
58 | struct device_attribute *attr, char *); | 58 | struct device_attribute *attr, char *); |
59 | extern ssize_t tpm_show_timeouts(struct device *, | ||
60 | struct device_attribute *attr, char *); | ||
59 | 61 | ||
60 | struct tpm_chip; | 62 | struct tpm_chip; |
61 | 63 | ||
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 1030f8420137..3e1f2bbeec11 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
28 | #include <linux/acpi.h> | ||
28 | #include "tpm.h" | 29 | #include "tpm.h" |
29 | 30 | ||
30 | #define TPM_HEADER_SIZE 10 | 31 | #define TPM_HEADER_SIZE 10 |
@@ -78,6 +79,26 @@ enum tis_defaults { | |||
78 | static LIST_HEAD(tis_chips); | 79 | static LIST_HEAD(tis_chips); |
79 | static DEFINE_SPINLOCK(tis_lock); | 80 | static DEFINE_SPINLOCK(tis_lock); |
80 | 81 | ||
82 | #ifdef CONFIG_ACPI | ||
83 | static int is_itpm(struct pnp_dev *dev) | ||
84 | { | ||
85 | struct acpi_device *acpi = pnp_acpi_device(dev); | ||
86 | struct acpi_hardware_id *id; | ||
87 | |||
88 | list_for_each_entry(id, &acpi->pnp.ids, list) { | ||
89 | if (!strcmp("INTC0102", id->id)) | ||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | #else | ||
96 | static int is_itpm(struct pnp_dev *dev) | ||
97 | { | ||
98 | return 0; | ||
99 | } | ||
100 | #endif | ||
101 | |||
81 | static int check_locality(struct tpm_chip *chip, int l) | 102 | static int check_locality(struct tpm_chip *chip, int l) |
82 | { | 103 | { |
83 | if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) & | 104 | if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) & |
@@ -355,6 +376,7 @@ static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, | |||
355 | NULL); | 376 | NULL); |
356 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); | 377 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); |
357 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | 378 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); |
379 | static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL); | ||
358 | 380 | ||
359 | static struct attribute *tis_attrs[] = { | 381 | static struct attribute *tis_attrs[] = { |
360 | &dev_attr_pubek.attr, | 382 | &dev_attr_pubek.attr, |
@@ -364,7 +386,8 @@ static struct attribute *tis_attrs[] = { | |||
364 | &dev_attr_owned.attr, | 386 | &dev_attr_owned.attr, |
365 | &dev_attr_temp_deactivated.attr, | 387 | &dev_attr_temp_deactivated.attr, |
366 | &dev_attr_caps.attr, | 388 | &dev_attr_caps.attr, |
367 | &dev_attr_cancel.attr, NULL, | 389 | &dev_attr_cancel.attr, |
390 | &dev_attr_timeouts.attr, NULL, | ||
368 | }; | 391 | }; |
369 | 392 | ||
370 | static struct attribute_group tis_attr_grp = { | 393 | static struct attribute_group tis_attr_grp = { |
@@ -472,6 +495,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
472 | "1.2 TPM (device-id 0x%X, rev-id %d)\n", | 495 | "1.2 TPM (device-id 0x%X, rev-id %d)\n", |
473 | vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); | 496 | vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); |
474 | 497 | ||
498 | if (is_itpm(to_pnp_dev(dev))) | ||
499 | itpm = 1; | ||
500 | |||
475 | if (itpm) | 501 | if (itpm) |
476 | dev_info(dev, "Intel iTPM workaround enabled\n"); | 502 | dev_info(dev, "Intel iTPM workaround enabled\n"); |
477 | 503 | ||
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index cc1e9850d655..d8210ca00720 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c | |||
@@ -413,7 +413,8 @@ static void flush_to_ldisc(struct work_struct *work) | |||
413 | spin_lock_irqsave(&tty->buf.lock, flags); | 413 | spin_lock_irqsave(&tty->buf.lock, flags); |
414 | 414 | ||
415 | if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { | 415 | if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { |
416 | struct tty_buffer *head; | 416 | struct tty_buffer *head, *tail = tty->buf.tail; |
417 | int seen_tail = 0; | ||
417 | while ((head = tty->buf.head) != NULL) { | 418 | while ((head = tty->buf.head) != NULL) { |
418 | int count; | 419 | int count; |
419 | char *char_buf; | 420 | char *char_buf; |
@@ -423,6 +424,15 @@ static void flush_to_ldisc(struct work_struct *work) | |||
423 | if (!count) { | 424 | if (!count) { |
424 | if (head->next == NULL) | 425 | if (head->next == NULL) |
425 | break; | 426 | break; |
427 | /* | ||
428 | There's a possibility tty might get new buffer | ||
429 | added during the unlock window below. We could | ||
430 | end up spinning in here forever hogging the CPU | ||
431 | completely. To avoid this let's have a rest each | ||
432 | time we processed the tail buffer. | ||
433 | */ | ||
434 | if (tail == head) | ||
435 | seen_tail = 1; | ||
426 | tty->buf.head = head->next; | 436 | tty->buf.head = head->next; |
427 | tty_buffer_free(tty, head); | 437 | tty_buffer_free(tty, head); |
428 | continue; | 438 | continue; |
@@ -432,7 +442,7 @@ static void flush_to_ldisc(struct work_struct *work) | |||
432 | line discipline as we want to empty the queue */ | 442 | line discipline as we want to empty the queue */ |
433 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) | 443 | if (test_bit(TTY_FLUSHPENDING, &tty->flags)) |
434 | break; | 444 | break; |
435 | if (!tty->receive_room) { | 445 | if (!tty->receive_room || seen_tail) { |
436 | schedule_delayed_work(&tty->buf.work, 1); | 446 | schedule_delayed_work(&tty->buf.work, 1); |
437 | break; | 447 | break; |
438 | } | 448 | } |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 613c852ee0fe..e0f7f4b8c286 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -553,6 +553,9 @@ void __tty_hangup(struct tty_struct *tty) | |||
553 | 553 | ||
554 | tty_lock(); | 554 | tty_lock(); |
555 | 555 | ||
556 | /* some functions below drop BTM, so we need this bit */ | ||
557 | set_bit(TTY_HUPPING, &tty->flags); | ||
558 | |||
556 | /* inuse_filps is protected by the single tty lock, | 559 | /* inuse_filps is protected by the single tty lock, |
557 | this really needs to change if we want to flush the | 560 | this really needs to change if we want to flush the |
558 | workqueue with the lock held */ | 561 | workqueue with the lock held */ |
@@ -572,6 +575,10 @@ void __tty_hangup(struct tty_struct *tty) | |||
572 | } | 575 | } |
573 | spin_unlock(&tty_files_lock); | 576 | spin_unlock(&tty_files_lock); |
574 | 577 | ||
578 | /* | ||
579 | * it drops BTM and thus races with reopen | ||
580 | * we protect the race by TTY_HUPPING | ||
581 | */ | ||
575 | tty_ldisc_hangup(tty); | 582 | tty_ldisc_hangup(tty); |
576 | 583 | ||
577 | read_lock(&tasklist_lock); | 584 | read_lock(&tasklist_lock); |
@@ -609,7 +616,6 @@ void __tty_hangup(struct tty_struct *tty) | |||
609 | tty->session = NULL; | 616 | tty->session = NULL; |
610 | tty->pgrp = NULL; | 617 | tty->pgrp = NULL; |
611 | tty->ctrl_status = 0; | 618 | tty->ctrl_status = 0; |
612 | set_bit(TTY_HUPPED, &tty->flags); | ||
613 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 619 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
614 | 620 | ||
615 | /* Account for the p->signal references we killed */ | 621 | /* Account for the p->signal references we killed */ |
@@ -635,6 +641,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
635 | * can't yet guarantee all that. | 641 | * can't yet guarantee all that. |
636 | */ | 642 | */ |
637 | set_bit(TTY_HUPPED, &tty->flags); | 643 | set_bit(TTY_HUPPED, &tty->flags); |
644 | clear_bit(TTY_HUPPING, &tty->flags); | ||
638 | tty_ldisc_enable(tty); | 645 | tty_ldisc_enable(tty); |
639 | 646 | ||
640 | tty_unlock(); | 647 | tty_unlock(); |
@@ -1304,7 +1311,9 @@ static int tty_reopen(struct tty_struct *tty) | |||
1304 | { | 1311 | { |
1305 | struct tty_driver *driver = tty->driver; | 1312 | struct tty_driver *driver = tty->driver; |
1306 | 1313 | ||
1307 | if (test_bit(TTY_CLOSING, &tty->flags)) | 1314 | if (test_bit(TTY_CLOSING, &tty->flags) || |
1315 | test_bit(TTY_HUPPING, &tty->flags) || | ||
1316 | test_bit(TTY_LDISC_CHANGING, &tty->flags)) | ||
1308 | return -EIO; | 1317 | return -EIO; |
1309 | 1318 | ||
1310 | if (driver->type == TTY_DRIVER_TYPE_PTY && | 1319 | if (driver->type == TTY_DRIVER_TYPE_PTY && |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 412f9775d19c..4214d58276f7 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -47,6 +47,7 @@ | |||
47 | 47 | ||
48 | static DEFINE_SPINLOCK(tty_ldisc_lock); | 48 | static DEFINE_SPINLOCK(tty_ldisc_lock); |
49 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); | 49 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); |
50 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle); | ||
50 | /* Line disc dispatch table */ | 51 | /* Line disc dispatch table */ |
51 | static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; | 52 | static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; |
52 | 53 | ||
@@ -83,6 +84,7 @@ static void put_ldisc(struct tty_ldisc *ld) | |||
83 | return; | 84 | return; |
84 | } | 85 | } |
85 | local_irq_restore(flags); | 86 | local_irq_restore(flags); |
87 | wake_up(&tty_ldisc_idle); | ||
86 | } | 88 | } |
87 | 89 | ||
88 | /** | 90 | /** |
@@ -452,6 +454,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) | |||
452 | /* BTM here locks versus a hangup event */ | 454 | /* BTM here locks versus a hangup event */ |
453 | WARN_ON(!tty_locked()); | 455 | WARN_ON(!tty_locked()); |
454 | ret = ld->ops->open(tty); | 456 | ret = ld->ops->open(tty); |
457 | if (ret) | ||
458 | clear_bit(TTY_LDISC_OPEN, &tty->flags); | ||
455 | return ret; | 459 | return ret; |
456 | } | 460 | } |
457 | return 0; | 461 | return 0; |
@@ -531,6 +535,23 @@ static int tty_ldisc_halt(struct tty_struct *tty) | |||
531 | } | 535 | } |
532 | 536 | ||
533 | /** | 537 | /** |
538 | * tty_ldisc_wait_idle - wait for the ldisc to become idle | ||
539 | * @tty: tty to wait for | ||
540 | * | ||
541 | * Wait for the line discipline to become idle. The discipline must | ||
542 | * have been halted for this to guarantee it remains idle. | ||
543 | */ | ||
544 | static int tty_ldisc_wait_idle(struct tty_struct *tty) | ||
545 | { | ||
546 | int ret; | ||
547 | ret = wait_event_interruptible_timeout(tty_ldisc_idle, | ||
548 | atomic_read(&tty->ldisc->users) == 1, 5 * HZ); | ||
549 | if (ret < 0) | ||
550 | return ret; | ||
551 | return ret > 0 ? 0 : -EBUSY; | ||
552 | } | ||
553 | |||
554 | /** | ||
534 | * tty_set_ldisc - set line discipline | 555 | * tty_set_ldisc - set line discipline |
535 | * @tty: the terminal to set | 556 | * @tty: the terminal to set |
536 | * @ldisc: the line discipline | 557 | * @ldisc: the line discipline |
@@ -634,8 +655,17 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
634 | 655 | ||
635 | flush_scheduled_work(); | 656 | flush_scheduled_work(); |
636 | 657 | ||
658 | retval = tty_ldisc_wait_idle(tty); | ||
659 | |||
637 | tty_lock(); | 660 | tty_lock(); |
638 | mutex_lock(&tty->ldisc_mutex); | 661 | mutex_lock(&tty->ldisc_mutex); |
662 | |||
663 | /* handle wait idle failure locked */ | ||
664 | if (retval) { | ||
665 | tty_ldisc_put(new_ldisc); | ||
666 | goto enable; | ||
667 | } | ||
668 | |||
639 | if (test_bit(TTY_HUPPED, &tty->flags)) { | 669 | if (test_bit(TTY_HUPPED, &tty->flags)) { |
640 | /* We were raced by the hangup method. It will have stomped | 670 | /* We were raced by the hangup method. It will have stomped |
641 | the ldisc data and closed the ldisc down */ | 671 | the ldisc data and closed the ldisc down */ |
@@ -669,6 +699,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
669 | 699 | ||
670 | tty_ldisc_put(o_ldisc); | 700 | tty_ldisc_put(o_ldisc); |
671 | 701 | ||
702 | enable: | ||
672 | /* | 703 | /* |
673 | * Allow ldisc referencing to occur again | 704 | * Allow ldisc referencing to occur again |
674 | */ | 705 | */ |
@@ -714,9 +745,12 @@ static void tty_reset_termios(struct tty_struct *tty) | |||
714 | * state closed | 745 | * state closed |
715 | */ | 746 | */ |
716 | 747 | ||
717 | static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc) | 748 | static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) |
718 | { | 749 | { |
719 | struct tty_ldisc *ld; | 750 | struct tty_ldisc *ld = tty_ldisc_get(ldisc); |
751 | |||
752 | if (IS_ERR(ld)) | ||
753 | return -1; | ||
720 | 754 | ||
721 | tty_ldisc_close(tty, tty->ldisc); | 755 | tty_ldisc_close(tty, tty->ldisc); |
722 | tty_ldisc_put(tty->ldisc); | 756 | tty_ldisc_put(tty->ldisc); |
@@ -724,10 +758,10 @@ static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc) | |||
724 | /* | 758 | /* |
725 | * Switch the line discipline back | 759 | * Switch the line discipline back |
726 | */ | 760 | */ |
727 | ld = tty_ldisc_get(ldisc); | ||
728 | BUG_ON(IS_ERR(ld)); | ||
729 | tty_ldisc_assign(tty, ld); | 761 | tty_ldisc_assign(tty, ld); |
730 | tty_set_termios_ldisc(tty, ldisc); | 762 | tty_set_termios_ldisc(tty, ldisc); |
763 | |||
764 | return 0; | ||
731 | } | 765 | } |
732 | 766 | ||
733 | /** | 767 | /** |
@@ -802,13 +836,16 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
802 | a FIXME */ | 836 | a FIXME */ |
803 | if (tty->ldisc) { /* Not yet closed */ | 837 | if (tty->ldisc) { /* Not yet closed */ |
804 | if (reset == 0) { | 838 | if (reset == 0) { |
805 | tty_ldisc_reinit(tty, tty->termios->c_line); | 839 | |
806 | err = tty_ldisc_open(tty, tty->ldisc); | 840 | if (!tty_ldisc_reinit(tty, tty->termios->c_line)) |
841 | err = tty_ldisc_open(tty, tty->ldisc); | ||
842 | else | ||
843 | err = 1; | ||
807 | } | 844 | } |
808 | /* If the re-open fails or we reset then go to N_TTY. The | 845 | /* If the re-open fails or we reset then go to N_TTY. The |
809 | N_TTY open cannot fail */ | 846 | N_TTY open cannot fail */ |
810 | if (reset || err) { | 847 | if (reset || err) { |
811 | tty_ldisc_reinit(tty, N_TTY); | 848 | BUG_ON(tty_ldisc_reinit(tty, N_TTY)); |
812 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); | 849 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); |
813 | } | 850 | } |
814 | tty_ldisc_enable(tty); | 851 | tty_ldisc_enable(tty); |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 0f69c5ec0ecd..7dc855b074d3 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -1314,6 +1314,17 @@ static void control_work_handler(struct work_struct *work) | |||
1314 | spin_unlock(&portdev->cvq_lock); | 1314 | spin_unlock(&portdev->cvq_lock); |
1315 | } | 1315 | } |
1316 | 1316 | ||
1317 | static void out_intr(struct virtqueue *vq) | ||
1318 | { | ||
1319 | struct port *port; | ||
1320 | |||
1321 | port = find_port_by_vq(vq->vdev->priv, vq); | ||
1322 | if (!port) | ||
1323 | return; | ||
1324 | |||
1325 | wake_up_interruptible(&port->waitqueue); | ||
1326 | } | ||
1327 | |||
1317 | static void in_intr(struct virtqueue *vq) | 1328 | static void in_intr(struct virtqueue *vq) |
1318 | { | 1329 | { |
1319 | struct port *port; | 1330 | struct port *port; |
@@ -1430,7 +1441,7 @@ static int init_vqs(struct ports_device *portdev) | |||
1430 | */ | 1441 | */ |
1431 | j = 0; | 1442 | j = 0; |
1432 | io_callbacks[j] = in_intr; | 1443 | io_callbacks[j] = in_intr; |
1433 | io_callbacks[j + 1] = NULL; | 1444 | io_callbacks[j + 1] = out_intr; |
1434 | io_names[j] = "input"; | 1445 | io_names[j] = "input"; |
1435 | io_names[j + 1] = "output"; | 1446 | io_names[j + 1] = "output"; |
1436 | j += 2; | 1447 | j += 2; |
@@ -1444,7 +1455,7 @@ static int init_vqs(struct ports_device *portdev) | |||
1444 | for (i = 1; i < nr_ports; i++) { | 1455 | for (i = 1; i < nr_ports; i++) { |
1445 | j += 2; | 1456 | j += 2; |
1446 | io_callbacks[j] = in_intr; | 1457 | io_callbacks[j] = in_intr; |
1447 | io_callbacks[j + 1] = NULL; | 1458 | io_callbacks[j + 1] = out_intr; |
1448 | io_names[j] = "input"; | 1459 | io_names[j] = "input"; |
1449 | io_names[j + 1] = "output"; | 1460 | io_names[j + 1] = "output"; |
1450 | } | 1461 | } |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 38df8c19e74c..6b68a0fb4611 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -503,6 +503,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
503 | struct kbd_struct * kbd; | 503 | struct kbd_struct * kbd; |
504 | unsigned int console; | 504 | unsigned int console; |
505 | unsigned char ucval; | 505 | unsigned char ucval; |
506 | unsigned int uival; | ||
506 | void __user *up = (void __user *)arg; | 507 | void __user *up = (void __user *)arg; |
507 | int i, perm; | 508 | int i, perm; |
508 | int ret = 0; | 509 | int ret = 0; |
@@ -657,7 +658,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
657 | break; | 658 | break; |
658 | 659 | ||
659 | case KDGETMODE: | 660 | case KDGETMODE: |
660 | ucval = vc->vc_mode; | 661 | uival = vc->vc_mode; |
661 | goto setint; | 662 | goto setint; |
662 | 663 | ||
663 | case KDMAPDISP: | 664 | case KDMAPDISP: |
@@ -695,7 +696,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
695 | break; | 696 | break; |
696 | 697 | ||
697 | case KDGKBMODE: | 698 | case KDGKBMODE: |
698 | ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : | 699 | uival = ((kbd->kbdmode == VC_RAW) ? K_RAW : |
699 | (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : | 700 | (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : |
700 | (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : | 701 | (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : |
701 | K_XLATE); | 702 | K_XLATE); |
@@ -717,9 +718,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
717 | break; | 718 | break; |
718 | 719 | ||
719 | case KDGKBMETA: | 720 | case KDGKBMETA: |
720 | ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); | 721 | uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); |
721 | setint: | 722 | setint: |
722 | ret = put_user(ucval, (int __user *)arg); | 723 | ret = put_user(uival, (int __user *)arg); |
723 | break; | 724 | break; |
724 | 725 | ||
725 | case KDGETKEYCODE: | 726 | case KDGETKEYCODE: |
@@ -949,7 +950,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
949 | for (i = 0; i < MAX_NR_CONSOLES; ++i) | 950 | for (i = 0; i < MAX_NR_CONSOLES; ++i) |
950 | if (! VT_IS_IN_USE(i)) | 951 | if (! VT_IS_IN_USE(i)) |
951 | break; | 952 | break; |
952 | ucval = i < MAX_NR_CONSOLES ? (i+1) : -1; | 953 | uival = i < MAX_NR_CONSOLES ? (i+1) : -1; |
953 | goto setint; | 954 | goto setint; |
954 | 955 | ||
955 | /* | 956 | /* |