diff options
Diffstat (limited to 'drivers/char')
60 files changed, 1513 insertions, 4329 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 6aad99ec4e0f..31be3ac2e21b 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -201,19 +201,6 @@ config DIGIEPCA | |||
201 | To compile this driver as a module, choose M here: the | 201 | To compile this driver as a module, choose M here: the |
202 | module will be called epca. | 202 | module will be called epca. |
203 | 203 | ||
204 | config ESPSERIAL | ||
205 | tristate "Hayes ESP serial port support" | ||
206 | depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API && BROKEN | ||
207 | help | ||
208 | This is a driver which supports Hayes ESP serial ports. Both single | ||
209 | port cards and multiport cards are supported. Make sure to read | ||
210 | <file:Documentation/hayes-esp.txt>. | ||
211 | |||
212 | To compile this driver as a module, choose M here: the | ||
213 | module will be called esp. | ||
214 | |||
215 | If unsure, say N. | ||
216 | |||
217 | config MOXA_INTELLIO | 204 | config MOXA_INTELLIO |
218 | tristate "Moxa Intellio support" | 205 | tristate "Moxa Intellio support" |
219 | depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) | 206 | depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) |
@@ -515,7 +502,7 @@ config BRIQ_PANEL | |||
515 | 502 | ||
516 | config BFIN_OTP | 503 | config BFIN_OTP |
517 | tristate "Blackfin On-Chip OTP Memory Support" | 504 | tristate "Blackfin On-Chip OTP Memory Support" |
518 | depends on BLACKFIN && (BF52x || BF54x) | 505 | depends on BLACKFIN && (BF51x || BF52x || BF54x) |
519 | default y | 506 | default y |
520 | help | 507 | help |
521 | If you say Y here, you will get support for a character device | 508 | If you say Y here, you will get support for a character device |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 19a79dd79eee..f957edf7e45d 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -18,7 +18,6 @@ obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o | |||
18 | obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o | 18 | obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o |
19 | obj-$(CONFIG_AUDIT) += tty_audit.o | 19 | obj-$(CONFIG_AUDIT) += tty_audit.o |
20 | obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o | 20 | obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o |
21 | obj-$(CONFIG_ESPSERIAL) += esp.o | ||
22 | obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o | 21 | obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o |
23 | obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o | 22 | obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o |
24 | obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o | 23 | obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o |
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index ccb1fa89de29..2fb3a480f6b0 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -56,9 +56,8 @@ config AGP_AMD | |||
56 | X on AMD Irongate, 761, and 762 chipsets. | 56 | X on AMD Irongate, 761, and 762 chipsets. |
57 | 57 | ||
58 | config AGP_AMD64 | 58 | config AGP_AMD64 |
59 | tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU | 59 | tristate "AMD Opteron/Athlon64 on-CPU GART support" |
60 | depends on AGP && X86 | 60 | depends on AGP && X86 |
61 | default y if GART_IOMMU | ||
62 | help | 61 | help |
63 | This option gives you AGP support for the GLX component of | 62 | This option gives you AGP support for the GLX component of |
64 | X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. | 63 | X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 2fb2e6cc322a..5aa7a586a7ff 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -725,9 +725,14 @@ static struct pci_driver agp_amd64_pci_driver = { | |||
725 | int __init agp_amd64_init(void) | 725 | int __init agp_amd64_init(void) |
726 | { | 726 | { |
727 | int err = 0; | 727 | int err = 0; |
728 | static int done = 0; | ||
728 | 729 | ||
729 | if (agp_off) | 730 | if (agp_off) |
730 | return -EINVAL; | 731 | return -EINVAL; |
732 | |||
733 | if (done++) | ||
734 | return agp_bridges_found ? 0 : -ENODEV; | ||
735 | |||
731 | err = pci_register_driver(&agp_amd64_pci_driver); | 736 | err = pci_register_driver(&agp_amd64_pci_driver); |
732 | if (err < 0) | 737 | if (err < 0) |
733 | return err; | 738 | return err; |
@@ -771,12 +776,8 @@ static void __exit agp_amd64_cleanup(void) | |||
771 | pci_unregister_driver(&agp_amd64_pci_driver); | 776 | pci_unregister_driver(&agp_amd64_pci_driver); |
772 | } | 777 | } |
773 | 778 | ||
774 | /* On AMD64 the PCI driver needs to initialize this driver early | ||
775 | for the IOMMU, so it has to be called via a backdoor. */ | ||
776 | #ifndef CONFIG_GART_IOMMU | ||
777 | module_init(agp_amd64_init); | 779 | module_init(agp_amd64_init); |
778 | module_exit(agp_amd64_cleanup); | 780 | module_exit(agp_amd64_cleanup); |
779 | #endif | ||
780 | 781 | ||
781 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen"); | 782 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen"); |
782 | module_param(agp_try_unsupported, bool, 0); | 783 | module_param(agp_try_unsupported, bool, 0); |
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index a96f3197e60f..43412c03969e 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c | |||
@@ -676,25 +676,25 @@ static int agp_open(struct inode *inode, struct file *file) | |||
676 | int minor = iminor(inode); | 676 | int minor = iminor(inode); |
677 | struct agp_file_private *priv; | 677 | struct agp_file_private *priv; |
678 | struct agp_client *client; | 678 | struct agp_client *client; |
679 | int rc = -ENXIO; | ||
680 | |||
681 | lock_kernel(); | ||
682 | mutex_lock(&(agp_fe.agp_mutex)); | ||
683 | 679 | ||
684 | if (minor != AGPGART_MINOR) | 680 | if (minor != AGPGART_MINOR) |
685 | goto err_out; | 681 | return -ENXIO; |
682 | |||
683 | mutex_lock(&(agp_fe.agp_mutex)); | ||
686 | 684 | ||
687 | priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL); | 685 | priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL); |
688 | if (priv == NULL) | 686 | if (priv == NULL) { |
689 | goto err_out_nomem; | 687 | mutex_unlock(&(agp_fe.agp_mutex)); |
688 | return -ENOMEM; | ||
689 | } | ||
690 | 690 | ||
691 | set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags); | 691 | set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags); |
692 | priv->my_pid = current->pid; | 692 | priv->my_pid = current->pid; |
693 | 693 | ||
694 | if (capable(CAP_SYS_RAWIO)) { | 694 | if (capable(CAP_SYS_RAWIO)) |
695 | /* Root priv, can be controller */ | 695 | /* Root priv, can be controller */ |
696 | set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags); | 696 | set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags); |
697 | } | 697 | |
698 | client = agp_find_client_by_pid(current->pid); | 698 | client = agp_find_client_by_pid(current->pid); |
699 | 699 | ||
700 | if (client != NULL) { | 700 | if (client != NULL) { |
@@ -704,16 +704,10 @@ static int agp_open(struct inode *inode, struct file *file) | |||
704 | file->private_data = (void *) priv; | 704 | file->private_data = (void *) priv; |
705 | agp_insert_file_private(priv); | 705 | agp_insert_file_private(priv); |
706 | DBG("private=%p, client=%p", priv, client); | 706 | DBG("private=%p, client=%p", priv, client); |
707 | mutex_unlock(&(agp_fe.agp_mutex)); | ||
708 | unlock_kernel(); | ||
709 | return 0; | ||
710 | 707 | ||
711 | err_out_nomem: | ||
712 | rc = -ENOMEM; | ||
713 | err_out: | ||
714 | mutex_unlock(&(agp_fe.agp_mutex)); | 708 | mutex_unlock(&(agp_fe.agp_mutex)); |
715 | unlock_kernel(); | 709 | |
716 | return rc; | 710 | return 0; |
717 | } | 711 | } |
718 | 712 | ||
719 | 713 | ||
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 3cb56a049e24..30c36ac2cd00 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -36,10 +36,10 @@ | |||
36 | #define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12 | 36 | #define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12 |
37 | #define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC | 37 | #define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC |
38 | #define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE | 38 | #define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE |
39 | #define PCI_DEVICE_ID_INTEL_IGDGM_HB 0xA010 | 39 | #define PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB 0xA010 |
40 | #define PCI_DEVICE_ID_INTEL_IGDGM_IG 0xA011 | 40 | #define PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG 0xA011 |
41 | #define PCI_DEVICE_ID_INTEL_IGDG_HB 0xA000 | 41 | #define PCI_DEVICE_ID_INTEL_PINEVIEW_HB 0xA000 |
42 | #define PCI_DEVICE_ID_INTEL_IGDG_IG 0xA001 | 42 | #define PCI_DEVICE_ID_INTEL_PINEVIEW_IG 0xA001 |
43 | #define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0 | 43 | #define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0 |
44 | #define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2 | 44 | #define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2 |
45 | #define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0 | 45 | #define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0 |
@@ -50,20 +50,20 @@ | |||
50 | #define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42 | 50 | #define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42 |
51 | #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 | 51 | #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 |
52 | #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 | 52 | #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 |
53 | #define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00 | 53 | #define PCI_DEVICE_ID_INTEL_EAGLELAKE_HB 0x2E00 |
54 | #define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02 | 54 | #define PCI_DEVICE_ID_INTEL_EAGLELAKE_IG 0x2E02 |
55 | #define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10 | 55 | #define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10 |
56 | #define PCI_DEVICE_ID_INTEL_Q45_IG 0x2E12 | 56 | #define PCI_DEVICE_ID_INTEL_Q45_IG 0x2E12 |
57 | #define PCI_DEVICE_ID_INTEL_G45_HB 0x2E20 | 57 | #define PCI_DEVICE_ID_INTEL_G45_HB 0x2E20 |
58 | #define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22 | 58 | #define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22 |
59 | #define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 | 59 | #define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 |
60 | #define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 | 60 | #define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 |
61 | #define PCI_DEVICE_ID_INTEL_IGDNG_D_HB 0x0040 | 61 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB 0x0040 |
62 | #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 | 62 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG 0x0042 |
63 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 | 63 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB 0x0044 |
64 | #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 | 64 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB 0x0062 |
65 | #define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB 0x006a | 65 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB 0x006a |
66 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 | 66 | #define PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG 0x0046 |
67 | 67 | ||
68 | /* cover 915 and 945 variants */ | 68 | /* cover 915 and 945 variants */ |
69 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ | 69 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ |
@@ -83,22 +83,22 @@ | |||
83 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ | 83 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ |
84 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ | 84 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ |
85 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \ | 85 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \ |
86 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \ | 86 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \ |
87 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB) | 87 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) |
88 | 88 | ||
89 | #define IS_IGD (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \ | 89 | #define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \ |
90 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB) | 90 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) |
91 | 91 | ||
92 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \ | 92 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \ |
93 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ | 93 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ |
94 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ | 94 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ |
95 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ | 95 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ |
96 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \ | 96 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \ |
97 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ | 97 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ |
98 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ | 98 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \ |
99 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ | 99 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \ |
100 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \ | 100 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ |
101 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB) | 101 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB) |
102 | 102 | ||
103 | extern int agp_memory_reserved; | 103 | extern int agp_memory_reserved; |
104 | 104 | ||
@@ -178,6 +178,7 @@ static struct _intel_private { | |||
178 | * popup and for the GTT. | 178 | * popup and for the GTT. |
179 | */ | 179 | */ |
180 | int gtt_entries; /* i830+ */ | 180 | int gtt_entries; /* i830+ */ |
181 | int gtt_total_size; | ||
181 | union { | 182 | union { |
182 | void __iomem *i9xx_flush_page; | 183 | void __iomem *i9xx_flush_page; |
183 | void *i8xx_flush_page; | 184 | void *i8xx_flush_page; |
@@ -653,7 +654,7 @@ static void intel_i830_init_gtt_entries(void) | |||
653 | size = 512; | 654 | size = 512; |
654 | } | 655 | } |
655 | size += 4; /* add in BIOS popup space */ | 656 | size += 4; /* add in BIOS popup space */ |
656 | } else if (IS_G33 && !IS_IGD) { | 657 | } else if (IS_G33 && !IS_PINEVIEW) { |
657 | /* G33's GTT size defined in gmch_ctrl */ | 658 | /* G33's GTT size defined in gmch_ctrl */ |
658 | switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { | 659 | switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { |
659 | case G33_PGETBL_SIZE_1M: | 660 | case G33_PGETBL_SIZE_1M: |
@@ -669,7 +670,7 @@ static void intel_i830_init_gtt_entries(void) | |||
669 | size = 512; | 670 | size = 512; |
670 | } | 671 | } |
671 | size += 4; | 672 | size += 4; |
672 | } else if (IS_G4X || IS_IGD) { | 673 | } else if (IS_G4X || IS_PINEVIEW) { |
673 | /* On 4 series hardware, GTT stolen is separate from graphics | 674 | /* On 4 series hardware, GTT stolen is separate from graphics |
674 | * stolen, ignore it in stolen gtt entries counting. However, | 675 | * stolen, ignore it in stolen gtt entries counting. However, |
675 | * 4KB of the stolen memory doesn't get mapped to the GTT. | 676 | * 4KB of the stolen memory doesn't get mapped to the GTT. |
@@ -1153,7 +1154,7 @@ static int intel_i915_configure(void) | |||
1153 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | 1154 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ |
1154 | 1155 | ||
1155 | if (agp_bridge->driver->needs_scratch_page) { | 1156 | if (agp_bridge->driver->needs_scratch_page) { |
1156 | for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { | 1157 | for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) { |
1157 | writel(agp_bridge->scratch_page, intel_private.gtt+i); | 1158 | writel(agp_bridge->scratch_page, intel_private.gtt+i); |
1158 | } | 1159 | } |
1159 | readl(intel_private.gtt+i-1); /* PCI Posting. */ | 1160 | readl(intel_private.gtt+i-1); /* PCI Posting. */ |
@@ -1308,6 +1309,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
1308 | if (!intel_private.gtt) | 1309 | if (!intel_private.gtt) |
1309 | return -ENOMEM; | 1310 | return -ENOMEM; |
1310 | 1311 | ||
1312 | intel_private.gtt_total_size = gtt_map_size / 4; | ||
1313 | |||
1311 | temp &= 0xfff80000; | 1314 | temp &= 0xfff80000; |
1312 | 1315 | ||
1313 | intel_private.registers = ioremap(temp, 128 * 4096); | 1316 | intel_private.registers = ioremap(temp, 128 * 4096); |
@@ -1352,15 +1355,15 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | |||
1352 | { | 1355 | { |
1353 | switch (agp_bridge->dev->device) { | 1356 | switch (agp_bridge->dev->device) { |
1354 | case PCI_DEVICE_ID_INTEL_GM45_HB: | 1357 | case PCI_DEVICE_ID_INTEL_GM45_HB: |
1355 | case PCI_DEVICE_ID_INTEL_IGD_E_HB: | 1358 | case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB: |
1356 | case PCI_DEVICE_ID_INTEL_Q45_HB: | 1359 | case PCI_DEVICE_ID_INTEL_Q45_HB: |
1357 | case PCI_DEVICE_ID_INTEL_G45_HB: | 1360 | case PCI_DEVICE_ID_INTEL_G45_HB: |
1358 | case PCI_DEVICE_ID_INTEL_G41_HB: | 1361 | case PCI_DEVICE_ID_INTEL_G41_HB: |
1359 | case PCI_DEVICE_ID_INTEL_B43_HB: | 1362 | case PCI_DEVICE_ID_INTEL_B43_HB: |
1360 | case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: | 1363 | case PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB: |
1361 | case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: | 1364 | case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB: |
1362 | case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: | 1365 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB: |
1363 | case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB: | 1366 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB: |
1364 | *gtt_offset = *gtt_size = MB(2); | 1367 | *gtt_offset = *gtt_size = MB(2); |
1365 | break; | 1368 | break; |
1366 | default: | 1369 | default: |
@@ -1395,6 +1398,8 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) | |||
1395 | if (!intel_private.gtt) | 1398 | if (!intel_private.gtt) |
1396 | return -ENOMEM; | 1399 | return -ENOMEM; |
1397 | 1400 | ||
1401 | intel_private.gtt_total_size = gtt_size / 4; | ||
1402 | |||
1398 | intel_private.registers = ioremap(temp, 128 * 4096); | 1403 | intel_private.registers = ioremap(temp, 128 * 4096); |
1399 | if (!intel_private.registers) { | 1404 | if (!intel_private.registers) { |
1400 | iounmap(intel_private.gtt); | 1405 | iounmap(intel_private.gtt); |
@@ -2340,14 +2345,14 @@ static const struct intel_driver_description { | |||
2340 | NULL, &intel_g33_driver }, | 2345 | NULL, &intel_g33_driver }, |
2341 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", | 2346 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", |
2342 | NULL, &intel_g33_driver }, | 2347 | NULL, &intel_g33_driver }, |
2343 | { PCI_DEVICE_ID_INTEL_IGDGM_HB, PCI_DEVICE_ID_INTEL_IGDGM_IG, 0, "IGD", | 2348 | { PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, 0, "Pineview", |
2344 | NULL, &intel_g33_driver }, | 2349 | NULL, &intel_g33_driver }, |
2345 | { PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD", | 2350 | { PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, 0, "Pineview", |
2346 | NULL, &intel_g33_driver }, | 2351 | NULL, &intel_g33_driver }, |
2347 | { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0, | 2352 | { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0, |
2348 | "Mobile Intel® GM45 Express", NULL, &intel_i965_driver }, | 2353 | "GM45", NULL, &intel_i965_driver }, |
2349 | { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0, | 2354 | { PCI_DEVICE_ID_INTEL_EAGLELAKE_HB, PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, 0, |
2350 | "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, | 2355 | "Eaglelake", NULL, &intel_i965_driver }, |
2351 | { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0, | 2356 | { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0, |
2352 | "Q45/Q43", NULL, &intel_i965_driver }, | 2357 | "Q45/Q43", NULL, &intel_i965_driver }, |
2353 | { PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0, | 2358 | { PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0, |
@@ -2356,14 +2361,14 @@ static const struct intel_driver_description { | |||
2356 | "B43", NULL, &intel_i965_driver }, | 2361 | "B43", NULL, &intel_i965_driver }, |
2357 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0, | 2362 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0, |
2358 | "G41", NULL, &intel_i965_driver }, | 2363 | "G41", NULL, &intel_i965_driver }, |
2359 | { PCI_DEVICE_ID_INTEL_IGDNG_D_HB, PCI_DEVICE_ID_INTEL_IGDNG_D_IG, 0, | 2364 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, 0, |
2360 | "IGDNG/D", NULL, &intel_i965_driver }, | 2365 | "Ironlake/D", NULL, &intel_i965_driver }, |
2361 | { PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, | 2366 | { PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, |
2362 | "IGDNG/M", NULL, &intel_i965_driver }, | 2367 | "Ironlake/M", NULL, &intel_i965_driver }, |
2363 | { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, | 2368 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, |
2364 | "IGDNG/MA", NULL, &intel_i965_driver }, | 2369 | "Ironlake/MA", NULL, &intel_i965_driver }, |
2365 | { PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, | 2370 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, 0, |
2366 | "IGDNG/MC2", NULL, &intel_i965_driver }, | 2371 | "Ironlake/MC2", NULL, &intel_i965_driver }, |
2367 | { 0, 0, 0, NULL, NULL, NULL } | 2372 | { 0, 0, 0, NULL, NULL, NULL } |
2368 | }; | 2373 | }; |
2369 | 2374 | ||
@@ -2545,8 +2550,8 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2545 | ID(PCI_DEVICE_ID_INTEL_82945G_HB), | 2550 | ID(PCI_DEVICE_ID_INTEL_82945G_HB), |
2546 | ID(PCI_DEVICE_ID_INTEL_82945GM_HB), | 2551 | ID(PCI_DEVICE_ID_INTEL_82945GM_HB), |
2547 | ID(PCI_DEVICE_ID_INTEL_82945GME_HB), | 2552 | ID(PCI_DEVICE_ID_INTEL_82945GME_HB), |
2548 | ID(PCI_DEVICE_ID_INTEL_IGDGM_HB), | 2553 | ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB), |
2549 | ID(PCI_DEVICE_ID_INTEL_IGDG_HB), | 2554 | ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB), |
2550 | ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), | 2555 | ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), |
2551 | ID(PCI_DEVICE_ID_INTEL_82G35_HB), | 2556 | ID(PCI_DEVICE_ID_INTEL_82G35_HB), |
2552 | ID(PCI_DEVICE_ID_INTEL_82965Q_HB), | 2557 | ID(PCI_DEVICE_ID_INTEL_82965Q_HB), |
@@ -2557,15 +2562,15 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2557 | ID(PCI_DEVICE_ID_INTEL_Q35_HB), | 2562 | ID(PCI_DEVICE_ID_INTEL_Q35_HB), |
2558 | ID(PCI_DEVICE_ID_INTEL_Q33_HB), | 2563 | ID(PCI_DEVICE_ID_INTEL_Q33_HB), |
2559 | ID(PCI_DEVICE_ID_INTEL_GM45_HB), | 2564 | ID(PCI_DEVICE_ID_INTEL_GM45_HB), |
2560 | ID(PCI_DEVICE_ID_INTEL_IGD_E_HB), | 2565 | ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB), |
2561 | ID(PCI_DEVICE_ID_INTEL_Q45_HB), | 2566 | ID(PCI_DEVICE_ID_INTEL_Q45_HB), |
2562 | ID(PCI_DEVICE_ID_INTEL_G45_HB), | 2567 | ID(PCI_DEVICE_ID_INTEL_G45_HB), |
2563 | ID(PCI_DEVICE_ID_INTEL_G41_HB), | 2568 | ID(PCI_DEVICE_ID_INTEL_G41_HB), |
2564 | ID(PCI_DEVICE_ID_INTEL_B43_HB), | 2569 | ID(PCI_DEVICE_ID_INTEL_B43_HB), |
2565 | ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), | 2570 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), |
2566 | ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), | 2571 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), |
2567 | ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), | 2572 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), |
2568 | ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB), | 2573 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), |
2569 | { } | 2574 | { } |
2570 | }; | 2575 | }; |
2571 | 2576 | ||
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 703959eba45a..d89da4ac061f 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
@@ -144,16 +144,13 @@ static int uninorth_configure(void) | |||
144 | return 0; | 144 | return 0; |
145 | } | 145 | } |
146 | 146 | ||
147 | static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, | 147 | static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, int type) |
148 | int type) | ||
149 | { | 148 | { |
150 | int i, j, num_entries; | 149 | int i, num_entries; |
151 | void *temp; | 150 | void *temp; |
151 | u32 *gp; | ||
152 | int mask_type; | 152 | int mask_type; |
153 | 153 | ||
154 | temp = agp_bridge->current_size; | ||
155 | num_entries = A_SIZE_32(temp)->num_entries; | ||
156 | |||
157 | if (type != mem->type) | 154 | if (type != mem->type) |
158 | return -EINVAL; | 155 | return -EINVAL; |
159 | 156 | ||
@@ -163,49 +160,12 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, | |||
163 | return -EINVAL; | 160 | return -EINVAL; |
164 | } | 161 | } |
165 | 162 | ||
166 | if ((pg_start + mem->page_count) > num_entries) | 163 | if (mem->page_count == 0) |
167 | return -EINVAL; | 164 | return 0; |
168 | |||
169 | j = pg_start; | ||
170 | |||
171 | while (j < (pg_start + mem->page_count)) { | ||
172 | if (agp_bridge->gatt_table[j]) | ||
173 | return -EBUSY; | ||
174 | j++; | ||
175 | } | ||
176 | |||
177 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | ||
178 | agp_bridge->gatt_table[j] = | ||
179 | cpu_to_le32((page_to_phys(mem->pages[i]) & 0xFFFFF000UL) | 0x1UL); | ||
180 | flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])), | ||
181 | (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000); | ||
182 | } | ||
183 | (void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]); | ||
184 | mb(); | ||
185 | |||
186 | uninorth_tlbflush(mem); | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | ||
191 | { | ||
192 | int i, num_entries; | ||
193 | void *temp; | ||
194 | u32 *gp; | ||
195 | int mask_type; | ||
196 | 165 | ||
197 | temp = agp_bridge->current_size; | 166 | temp = agp_bridge->current_size; |
198 | num_entries = A_SIZE_32(temp)->num_entries; | 167 | num_entries = A_SIZE_32(temp)->num_entries; |
199 | 168 | ||
200 | if (type != mem->type) | ||
201 | return -EINVAL; | ||
202 | |||
203 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | ||
204 | if (mask_type != 0) { | ||
205 | /* We know nothing of memory types */ | ||
206 | return -EINVAL; | ||
207 | } | ||
208 | |||
209 | if ((pg_start + mem->page_count) > num_entries) | 169 | if ((pg_start + mem->page_count) > num_entries) |
210 | return -EINVAL; | 170 | return -EINVAL; |
211 | 171 | ||
@@ -213,14 +173,18 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
213 | for (i = 0; i < mem->page_count; ++i) { | 173 | for (i = 0; i < mem->page_count; ++i) { |
214 | if (gp[i]) { | 174 | if (gp[i]) { |
215 | dev_info(&agp_bridge->dev->dev, | 175 | dev_info(&agp_bridge->dev->dev, |
216 | "u3_insert_memory: entry 0x%x occupied (%x)\n", | 176 | "uninorth_insert_memory: entry 0x%x occupied (%x)\n", |
217 | i, gp[i]); | 177 | i, gp[i]); |
218 | return -EBUSY; | 178 | return -EBUSY; |
219 | } | 179 | } |
220 | } | 180 | } |
221 | 181 | ||
222 | for (i = 0; i < mem->page_count; i++) { | 182 | for (i = 0; i < mem->page_count; i++) { |
223 | gp[i] = (page_to_phys(mem->pages[i]) >> PAGE_SHIFT) | 0x80000000UL; | 183 | if (is_u3) |
184 | gp[i] = (page_to_phys(mem->pages[i]) >> PAGE_SHIFT) | 0x80000000UL; | ||
185 | else | ||
186 | gp[i] = cpu_to_le32((page_to_phys(mem->pages[i]) & 0xFFFFF000UL) | | ||
187 | 0x1UL); | ||
224 | flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])), | 188 | flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])), |
225 | (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000); | 189 | (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000); |
226 | } | 190 | } |
@@ -230,14 +194,23 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
230 | return 0; | 194 | return 0; |
231 | } | 195 | } |
232 | 196 | ||
233 | int u3_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | 197 | int uninorth_remove_memory(struct agp_memory *mem, off_t pg_start, int type) |
234 | { | 198 | { |
235 | size_t i; | 199 | size_t i; |
236 | u32 *gp; | 200 | u32 *gp; |
201 | int mask_type; | ||
202 | |||
203 | if (type != mem->type) | ||
204 | return -EINVAL; | ||
237 | 205 | ||
238 | if (type != 0 || mem->type != 0) | 206 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); |
207 | if (mask_type != 0) { | ||
239 | /* We know nothing of memory types */ | 208 | /* We know nothing of memory types */ |
240 | return -EINVAL; | 209 | return -EINVAL; |
210 | } | ||
211 | |||
212 | if (mem->page_count == 0) | ||
213 | return 0; | ||
241 | 214 | ||
242 | gp = (u32 *) &agp_bridge->gatt_table[pg_start]; | 215 | gp = (u32 *) &agp_bridge->gatt_table[pg_start]; |
243 | for (i = 0; i < mem->page_count; ++i) | 216 | for (i = 0; i < mem->page_count; ++i) |
@@ -536,7 +509,7 @@ const struct agp_bridge_driver uninorth_agp_driver = { | |||
536 | .create_gatt_table = uninorth_create_gatt_table, | 509 | .create_gatt_table = uninorth_create_gatt_table, |
537 | .free_gatt_table = uninorth_free_gatt_table, | 510 | .free_gatt_table = uninorth_free_gatt_table, |
538 | .insert_memory = uninorth_insert_memory, | 511 | .insert_memory = uninorth_insert_memory, |
539 | .remove_memory = agp_generic_remove_memory, | 512 | .remove_memory = uninorth_remove_memory, |
540 | .alloc_by_type = agp_generic_alloc_by_type, | 513 | .alloc_by_type = agp_generic_alloc_by_type, |
541 | .free_by_type = agp_generic_free_by_type, | 514 | .free_by_type = agp_generic_free_by_type, |
542 | .agp_alloc_page = agp_generic_alloc_page, | 515 | .agp_alloc_page = agp_generic_alloc_page, |
@@ -562,8 +535,8 @@ const struct agp_bridge_driver u3_agp_driver = { | |||
562 | .agp_enable = uninorth_agp_enable, | 535 | .agp_enable = uninorth_agp_enable, |
563 | .create_gatt_table = uninorth_create_gatt_table, | 536 | .create_gatt_table = uninorth_create_gatt_table, |
564 | .free_gatt_table = uninorth_free_gatt_table, | 537 | .free_gatt_table = uninorth_free_gatt_table, |
565 | .insert_memory = u3_insert_memory, | 538 | .insert_memory = uninorth_insert_memory, |
566 | .remove_memory = u3_remove_memory, | 539 | .remove_memory = uninorth_remove_memory, |
567 | .alloc_by_type = agp_generic_alloc_by_type, | 540 | .alloc_by_type = agp_generic_alloc_by_type, |
568 | .free_by_type = agp_generic_free_by_type, | 541 | .free_by_type = agp_generic_free_by_type, |
569 | .agp_alloc_page = agp_generic_alloc_page, | 542 | .agp_alloc_page = agp_generic_alloc_page, |
diff --git a/drivers/char/bfin_jtag_comm.c b/drivers/char/bfin_jtag_comm.c index 1d7c34c73b20..2628c7415ea8 100644 --- a/drivers/char/bfin_jtag_comm.c +++ b/drivers/char/bfin_jtag_comm.c | |||
@@ -226,7 +226,7 @@ bfin_jc_wait_until_sent(struct tty_struct *tty, int timeout) | |||
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | static struct tty_operations bfin_jc_ops = { | 229 | static const struct tty_operations bfin_jc_ops = { |
230 | .open = bfin_jc_open, | 230 | .open = bfin_jc_open, |
231 | .close = bfin_jc_close, | 231 | .close = bfin_jc_close, |
232 | .write = bfin_jc_write, | 232 | .write = bfin_jc_write, |
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index 04ba906b4880..4d830dc482ef 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/cdev.h> | 17 | #include <linux/cdev.h> |
18 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
19 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <linux/smp_lock.h> | 20 | |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | 23 | ||
@@ -158,7 +158,6 @@ static int cs5535_gpio_open(struct inode *inode, struct file *file) | |||
158 | { | 158 | { |
159 | u32 m = iminor(inode); | 159 | u32 m = iminor(inode); |
160 | 160 | ||
161 | cycle_kernel_lock(); | ||
162 | /* the mask says which pins are usable by this driver */ | 161 | /* the mask says which pins are usable by this driver */ |
163 | if ((mask & (1 << m)) == 0) | 162 | if ((mask & (1 << m)) == 0) |
164 | return -EINVAL; | 163 | return -EINVAL; |
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c index 34d15d548236..53c524e7b829 100644 --- a/drivers/char/efirtc.c +++ b/drivers/char/efirtc.c | |||
@@ -27,8 +27,6 @@ | |||
27 | * - Add module support | 27 | * - Add module support |
28 | */ | 28 | */ |
29 | 29 | ||
30 | |||
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/types.h> | 30 | #include <linux/types.h> |
33 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
34 | #include <linux/miscdevice.h> | 32 | #include <linux/miscdevice.h> |
@@ -174,13 +172,12 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd, | |||
174 | return -EINVAL; | 172 | return -EINVAL; |
175 | 173 | ||
176 | case RTC_RD_TIME: | 174 | case RTC_RD_TIME: |
177 | lock_kernel(); | ||
178 | spin_lock_irqsave(&efi_rtc_lock, flags); | 175 | spin_lock_irqsave(&efi_rtc_lock, flags); |
179 | 176 | ||
180 | status = efi.get_time(&eft, &cap); | 177 | status = efi.get_time(&eft, &cap); |
181 | 178 | ||
182 | spin_unlock_irqrestore(&efi_rtc_lock,flags); | 179 | spin_unlock_irqrestore(&efi_rtc_lock,flags); |
183 | unlock_kernel(); | 180 | |
184 | if (status != EFI_SUCCESS) { | 181 | if (status != EFI_SUCCESS) { |
185 | /* should never happen */ | 182 | /* should never happen */ |
186 | printk(KERN_ERR "efitime: can't read time\n"); | 183 | printk(KERN_ERR "efitime: can't read time\n"); |
@@ -202,13 +199,11 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd, | |||
202 | 199 | ||
203 | convert_to_efi_time(&wtime, &eft); | 200 | convert_to_efi_time(&wtime, &eft); |
204 | 201 | ||
205 | lock_kernel(); | ||
206 | spin_lock_irqsave(&efi_rtc_lock, flags); | 202 | spin_lock_irqsave(&efi_rtc_lock, flags); |
207 | 203 | ||
208 | status = efi.set_time(&eft); | 204 | status = efi.set_time(&eft); |
209 | 205 | ||
210 | spin_unlock_irqrestore(&efi_rtc_lock,flags); | 206 | spin_unlock_irqrestore(&efi_rtc_lock,flags); |
211 | unlock_kernel(); | ||
212 | 207 | ||
213 | return status == EFI_SUCCESS ? 0 : -EINVAL; | 208 | return status == EFI_SUCCESS ? 0 : -EINVAL; |
214 | 209 | ||
@@ -224,7 +219,6 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd, | |||
224 | 219 | ||
225 | convert_to_efi_time(&wtime, &eft); | 220 | convert_to_efi_time(&wtime, &eft); |
226 | 221 | ||
227 | lock_kernel(); | ||
228 | spin_lock_irqsave(&efi_rtc_lock, flags); | 222 | spin_lock_irqsave(&efi_rtc_lock, flags); |
229 | /* | 223 | /* |
230 | * XXX Fixme: | 224 | * XXX Fixme: |
@@ -235,19 +229,16 @@ static long efi_rtc_ioctl(struct file *file, unsigned int cmd, | |||
235 | status = efi.set_wakeup_time((efi_bool_t)enabled, &eft); | 229 | status = efi.set_wakeup_time((efi_bool_t)enabled, &eft); |
236 | 230 | ||
237 | spin_unlock_irqrestore(&efi_rtc_lock,flags); | 231 | spin_unlock_irqrestore(&efi_rtc_lock,flags); |
238 | unlock_kernel(); | ||
239 | 232 | ||
240 | return status == EFI_SUCCESS ? 0 : -EINVAL; | 233 | return status == EFI_SUCCESS ? 0 : -EINVAL; |
241 | 234 | ||
242 | case RTC_WKALM_RD: | 235 | case RTC_WKALM_RD: |
243 | 236 | ||
244 | lock_kernel(); | ||
245 | spin_lock_irqsave(&efi_rtc_lock, flags); | 237 | spin_lock_irqsave(&efi_rtc_lock, flags); |
246 | 238 | ||
247 | status = efi.get_wakeup_time((efi_bool_t *)&enabled, (efi_bool_t *)&pending, &eft); | 239 | status = efi.get_wakeup_time((efi_bool_t *)&enabled, (efi_bool_t *)&pending, &eft); |
248 | 240 | ||
249 | spin_unlock_irqrestore(&efi_rtc_lock,flags); | 241 | spin_unlock_irqrestore(&efi_rtc_lock,flags); |
250 | unlock_kernel(); | ||
251 | 242 | ||
252 | if (status != EFI_SUCCESS) return -EINVAL; | 243 | if (status != EFI_SUCCESS) return -EINVAL; |
253 | 244 | ||
@@ -277,7 +268,6 @@ static int efi_rtc_open(struct inode *inode, struct file *file) | |||
277 | * We do accept multiple open files at the same time as we | 268 | * We do accept multiple open files at the same time as we |
278 | * synchronize on the per call operation. | 269 | * synchronize on the per call operation. |
279 | */ | 270 | */ |
280 | cycle_kernel_lock(); | ||
281 | return 0; | 271 | return 0; |
282 | } | 272 | } |
283 | 273 | ||
@@ -295,6 +285,7 @@ static const struct file_operations efi_rtc_fops = { | |||
295 | .unlocked_ioctl = efi_rtc_ioctl, | 285 | .unlocked_ioctl = efi_rtc_ioctl, |
296 | .open = efi_rtc_open, | 286 | .open = efi_rtc_open, |
297 | .release = efi_rtc_close, | 287 | .release = efi_rtc_close, |
288 | .llseek = no_llseek, | ||
298 | }; | 289 | }; |
299 | 290 | ||
300 | static struct miscdevice efi_rtc_dev= { | 291 | static struct miscdevice efi_rtc_dev= { |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index dde5134713e2..17b044a71e02 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -935,7 +935,7 @@ static int info_open(struct tty_struct *tty, struct file *filp) | |||
935 | return 0; | 935 | return 0; |
936 | } | 936 | } |
937 | 937 | ||
938 | static struct tty_operations info_ops = { | 938 | static const struct tty_operations info_ops = { |
939 | .open = info_open, | 939 | .open = info_open, |
940 | .ioctl = info_ioctl, | 940 | .ioctl = info_ioctl, |
941 | }; | 941 | }; |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c deleted file mode 100644 index b19d43cd9542..000000000000 --- a/drivers/char/esp.c +++ /dev/null | |||
@@ -1,2533 +0,0 @@ | |||
1 | /* | ||
2 | * esp.c - driver for Hayes ESP serial cards | ||
3 | * | ||
4 | * --- Notices from serial.c, upon which this driver is based --- | ||
5 | * | ||
6 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
7 | * | ||
8 | * Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now | ||
9 | * much more extensible to support other serial cards based on the | ||
10 | * 16450/16550A UART's. Added support for the AST FourPort and the | ||
11 | * Accent Async board. | ||
12 | * | ||
13 | * set_serial_info fixed to set the flags, custom divisor, and uart | ||
14 | * type fields. Fix suggested by Michael K. Johnson 12/12/92. | ||
15 | * | ||
16 | * 11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk> | ||
17 | * | ||
18 | * 03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk> | ||
19 | * | ||
20 | * rs_set_termios fixed to look also for changes of the input | ||
21 | * flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK. | ||
22 | * Bernd Anhäupl 05/17/96. | ||
23 | * | ||
24 | * --- End of notices from serial.c --- | ||
25 | * | ||
26 | * Support for the ESP serial card by Andrew J. Robinson | ||
27 | * <arobinso@nyx.net> (Card detection routine taken from a patch | ||
28 | * by Dennis J. Boylan). Patches to allow use with 2.1.x contributed | ||
29 | * by Chris Faylor. | ||
30 | * | ||
31 | * Most recent changes: (Andrew J. Robinson) | ||
32 | * Support for PIO mode. This allows the driver to work properly with | ||
33 | * multiport cards. | ||
34 | * | ||
35 | * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - | ||
36 | * several cleanups, use module_init/module_exit, etc | ||
37 | * | ||
38 | * This module exports the following rs232 io functions: | ||
39 | * | ||
40 | * int espserial_init(void); | ||
41 | */ | ||
42 | |||
43 | #include <linux/module.h> | ||
44 | #include <linux/errno.h> | ||
45 | #include <linux/signal.h> | ||
46 | #include <linux/sched.h> | ||
47 | #include <linux/interrupt.h> | ||
48 | #include <linux/tty.h> | ||
49 | #include <linux/tty_flip.h> | ||
50 | #include <linux/serial.h> | ||
51 | #include <linux/serialP.h> | ||
52 | #include <linux/serial_reg.h> | ||
53 | #include <linux/major.h> | ||
54 | #include <linux/string.h> | ||
55 | #include <linux/fcntl.h> | ||
56 | #include <linux/ptrace.h> | ||
57 | #include <linux/ioport.h> | ||
58 | #include <linux/mm.h> | ||
59 | #include <linux/init.h> | ||
60 | #include <linux/delay.h> | ||
61 | #include <linux/bitops.h> | ||
62 | |||
63 | #include <asm/system.h> | ||
64 | #include <linux/io.h> | ||
65 | |||
66 | #include <asm/dma.h> | ||
67 | #include <linux/slab.h> | ||
68 | #include <linux/uaccess.h> | ||
69 | |||
70 | #include <linux/hayesesp.h> | ||
71 | |||
72 | #define NR_PORTS 64 /* maximum number of ports */ | ||
73 | #define NR_PRIMARY 8 /* maximum number of primary ports */ | ||
74 | #define REGION_SIZE 8 /* size of io region to request */ | ||
75 | |||
76 | /* The following variables can be set by giving module options */ | ||
77 | static int irq[NR_PRIMARY]; /* IRQ for each base port */ | ||
78 | static unsigned int divisor[NR_PRIMARY]; /* custom divisor for each port */ | ||
79 | static unsigned int dma = ESP_DMA_CHANNEL; /* DMA channel */ | ||
80 | static unsigned int rx_trigger = ESP_RX_TRIGGER; | ||
81 | static unsigned int tx_trigger = ESP_TX_TRIGGER; | ||
82 | static unsigned int flow_off = ESP_FLOW_OFF; | ||
83 | static unsigned int flow_on = ESP_FLOW_ON; | ||
84 | static unsigned int rx_timeout = ESP_RX_TMOUT; | ||
85 | static unsigned int pio_threshold = ESP_PIO_THRESHOLD; | ||
86 | |||
87 | MODULE_LICENSE("GPL"); | ||
88 | |||
89 | module_param_array(irq, int, NULL, 0); | ||
90 | module_param_array(divisor, uint, NULL, 0); | ||
91 | module_param(dma, uint, 0); | ||
92 | module_param(rx_trigger, uint, 0); | ||
93 | module_param(tx_trigger, uint, 0); | ||
94 | module_param(flow_off, uint, 0); | ||
95 | module_param(flow_on, uint, 0); | ||
96 | module_param(rx_timeout, uint, 0); | ||
97 | module_param(pio_threshold, uint, 0); | ||
98 | |||
99 | /* END */ | ||
100 | |||
101 | static char *dma_buffer; | ||
102 | static int dma_bytes; | ||
103 | static struct esp_pio_buffer *free_pio_buf; | ||
104 | |||
105 | #define DMA_BUFFER_SZ 1024 | ||
106 | |||
107 | #define WAKEUP_CHARS 1024 | ||
108 | |||
109 | static char serial_name[] __initdata = "ESP serial driver"; | ||
110 | static char serial_version[] __initdata = "2.2"; | ||
111 | |||
112 | static struct tty_driver *esp_driver; | ||
113 | |||
114 | /* | ||
115 | * Serial driver configuration section. Here are the various options: | ||
116 | * | ||
117 | * SERIAL_PARANOIA_CHECK | ||
118 | * Check the magic number for the esp_structure where | ||
119 | * ever possible. | ||
120 | */ | ||
121 | |||
122 | #undef SERIAL_PARANOIA_CHECK | ||
123 | #define SERIAL_DO_RESTART | ||
124 | |||
125 | #undef SERIAL_DEBUG_INTR | ||
126 | #undef SERIAL_DEBUG_OPEN | ||
127 | #undef SERIAL_DEBUG_FLOW | ||
128 | |||
129 | #if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) | ||
130 | #define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ | ||
131 | tty->name, info->port.flags, \ | ||
132 | serial_driver.refcount, \ | ||
133 | info->port.count, tty->count, s) | ||
134 | #else | ||
135 | #define DBG_CNT(s) | ||
136 | #endif | ||
137 | |||
138 | static struct esp_struct *ports; | ||
139 | |||
140 | static void change_speed(struct esp_struct *info); | ||
141 | static void rs_wait_until_sent(struct tty_struct *, int); | ||
142 | |||
143 | /* | ||
144 | * The ESP card has a clock rate of 14.7456 MHz (that is, 2**ESPC_SCALE | ||
145 | * times the normal 1.8432 Mhz clock of most serial boards). | ||
146 | */ | ||
147 | #define BASE_BAUD ((1843200 / 16) * (1 << ESPC_SCALE)) | ||
148 | |||
149 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | ||
150 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | ||
151 | |||
152 | static inline int serial_paranoia_check(struct esp_struct *info, | ||
153 | char *name, const char *routine) | ||
154 | { | ||
155 | #ifdef SERIAL_PARANOIA_CHECK | ||
156 | static const char badmagic[] = KERN_WARNING | ||
157 | "Warning: bad magic number for serial struct (%s) in %s\n"; | ||
158 | static const char badinfo[] = KERN_WARNING | ||
159 | "Warning: null esp_struct for (%s) in %s\n"; | ||
160 | |||
161 | if (!info) { | ||
162 | printk(badinfo, name, routine); | ||
163 | return 1; | ||
164 | } | ||
165 | if (info->magic != ESP_MAGIC) { | ||
166 | printk(badmagic, name, routine); | ||
167 | return 1; | ||
168 | } | ||
169 | #endif | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static inline unsigned int serial_in(struct esp_struct *info, int offset) | ||
174 | { | ||
175 | return inb(info->io_port + offset); | ||
176 | } | ||
177 | |||
178 | static inline void serial_out(struct esp_struct *info, int offset, | ||
179 | unsigned char value) | ||
180 | { | ||
181 | outb(value, info->io_port+offset); | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * ------------------------------------------------------------ | ||
186 | * rs_stop() and rs_start() | ||
187 | * | ||
188 | * This routines are called before setting or resetting tty->stopped. | ||
189 | * They enable or disable transmitter interrupts, as necessary. | ||
190 | * ------------------------------------------------------------ | ||
191 | */ | ||
192 | static void rs_stop(struct tty_struct *tty) | ||
193 | { | ||
194 | struct esp_struct *info = tty->driver_data; | ||
195 | unsigned long flags; | ||
196 | |||
197 | if (serial_paranoia_check(info, tty->name, "rs_stop")) | ||
198 | return; | ||
199 | |||
200 | spin_lock_irqsave(&info->lock, flags); | ||
201 | if (info->IER & UART_IER_THRI) { | ||
202 | info->IER &= ~UART_IER_THRI; | ||
203 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
204 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
205 | } | ||
206 | spin_unlock_irqrestore(&info->lock, flags); | ||
207 | } | ||
208 | |||
209 | static void rs_start(struct tty_struct *tty) | ||
210 | { | ||
211 | struct esp_struct *info = tty->driver_data; | ||
212 | unsigned long flags; | ||
213 | |||
214 | if (serial_paranoia_check(info, tty->name, "rs_start")) | ||
215 | return; | ||
216 | |||
217 | spin_lock_irqsave(&info->lock, flags); | ||
218 | if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) { | ||
219 | info->IER |= UART_IER_THRI; | ||
220 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
221 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
222 | } | ||
223 | spin_unlock_irqrestore(&info->lock, flags); | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * ---------------------------------------------------------------------- | ||
228 | * | ||
229 | * Here starts the interrupt handling routines. All of the following | ||
230 | * subroutines are declared as inline and are folded into | ||
231 | * rs_interrupt(). They were separated out for readability's sake. | ||
232 | * | ||
233 | * Note: rs_interrupt() is a "fast" interrupt, which means that it | ||
234 | * runs with interrupts turned off. People who may want to modify | ||
235 | * rs_interrupt() should try to keep the interrupt handler as fast as | ||
236 | * possible. After you are done making modifications, it is not a bad | ||
237 | * idea to do: | ||
238 | * | ||
239 | * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c | ||
240 | * | ||
241 | * and look at the resulting assemble code in serial.s. | ||
242 | * | ||
243 | * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 | ||
244 | * ----------------------------------------------------------------------- | ||
245 | */ | ||
246 | |||
247 | static DEFINE_SPINLOCK(pio_lock); | ||
248 | |||
249 | static inline struct esp_pio_buffer *get_pio_buffer(void) | ||
250 | { | ||
251 | struct esp_pio_buffer *buf; | ||
252 | unsigned long flags; | ||
253 | |||
254 | spin_lock_irqsave(&pio_lock, flags); | ||
255 | if (free_pio_buf) { | ||
256 | buf = free_pio_buf; | ||
257 | free_pio_buf = buf->next; | ||
258 | } else { | ||
259 | buf = kmalloc(sizeof(struct esp_pio_buffer), GFP_ATOMIC); | ||
260 | } | ||
261 | spin_unlock_irqrestore(&pio_lock, flags); | ||
262 | return buf; | ||
263 | } | ||
264 | |||
265 | static inline void release_pio_buffer(struct esp_pio_buffer *buf) | ||
266 | { | ||
267 | unsigned long flags; | ||
268 | spin_lock_irqsave(&pio_lock, flags); | ||
269 | buf->next = free_pio_buf; | ||
270 | free_pio_buf = buf; | ||
271 | spin_unlock_irqrestore(&pio_lock, flags); | ||
272 | } | ||
273 | |||
274 | static inline void receive_chars_pio(struct esp_struct *info, int num_bytes) | ||
275 | { | ||
276 | struct tty_struct *tty = info->port.tty; | ||
277 | int i; | ||
278 | struct esp_pio_buffer *pio_buf; | ||
279 | struct esp_pio_buffer *err_buf; | ||
280 | unsigned char status_mask; | ||
281 | |||
282 | pio_buf = get_pio_buffer(); | ||
283 | |||
284 | if (!pio_buf) | ||
285 | return; | ||
286 | |||
287 | err_buf = get_pio_buffer(); | ||
288 | |||
289 | if (!err_buf) { | ||
290 | release_pio_buffer(pio_buf); | ||
291 | return; | ||
292 | } | ||
293 | |||
294 | status_mask = (info->read_status_mask >> 2) & 0x07; | ||
295 | |||
296 | for (i = 0; i < num_bytes - 1; i += 2) { | ||
297 | *((unsigned short *)(pio_buf->data + i)) = | ||
298 | inw(info->io_port + UART_ESI_RX); | ||
299 | err_buf->data[i] = serial_in(info, UART_ESI_RWS); | ||
300 | err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask; | ||
301 | err_buf->data[i] &= status_mask; | ||
302 | } | ||
303 | |||
304 | if (num_bytes & 0x0001) { | ||
305 | pio_buf->data[num_bytes - 1] = serial_in(info, UART_ESI_RX); | ||
306 | err_buf->data[num_bytes - 1] = | ||
307 | (serial_in(info, UART_ESI_RWS) >> 3) & status_mask; | ||
308 | } | ||
309 | |||
310 | /* make sure everything is still ok since interrupts were enabled */ | ||
311 | tty = info->port.tty; | ||
312 | |||
313 | if (!tty) { | ||
314 | release_pio_buffer(pio_buf); | ||
315 | release_pio_buffer(err_buf); | ||
316 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; | ||
317 | return; | ||
318 | } | ||
319 | |||
320 | status_mask = (info->ignore_status_mask >> 2) & 0x07; | ||
321 | |||
322 | for (i = 0; i < num_bytes; i++) { | ||
323 | if (!(err_buf->data[i] & status_mask)) { | ||
324 | int flag = 0; | ||
325 | |||
326 | if (err_buf->data[i] & 0x04) { | ||
327 | flag = TTY_BREAK; | ||
328 | if (info->port.flags & ASYNC_SAK) | ||
329 | do_SAK(tty); | ||
330 | } else if (err_buf->data[i] & 0x02) | ||
331 | flag = TTY_FRAME; | ||
332 | else if (err_buf->data[i] & 0x01) | ||
333 | flag = TTY_PARITY; | ||
334 | tty_insert_flip_char(tty, pio_buf->data[i], flag); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | tty_schedule_flip(tty); | ||
339 | |||
340 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; | ||
341 | release_pio_buffer(pio_buf); | ||
342 | release_pio_buffer(err_buf); | ||
343 | } | ||
344 | |||
345 | static void program_isa_dma(int dma, int dir, unsigned long addr, int len) | ||
346 | { | ||
347 | unsigned long flags; | ||
348 | |||
349 | flags = claim_dma_lock(); | ||
350 | disable_dma(dma); | ||
351 | clear_dma_ff(dma); | ||
352 | set_dma_mode(dma, dir); | ||
353 | set_dma_addr(dma, addr); | ||
354 | set_dma_count(dma, len); | ||
355 | enable_dma(dma); | ||
356 | release_dma_lock(flags); | ||
357 | } | ||
358 | |||
359 | static void receive_chars_dma(struct esp_struct *info, int num_bytes) | ||
360 | { | ||
361 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; | ||
362 | dma_bytes = num_bytes; | ||
363 | info->stat_flags |= ESP_STAT_DMA_RX; | ||
364 | |||
365 | program_isa_dma(dma, DMA_MODE_READ, isa_virt_to_bus(dma_buffer), | ||
366 | dma_bytes); | ||
367 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX); | ||
368 | } | ||
369 | |||
370 | static inline void receive_chars_dma_done(struct esp_struct *info, | ||
371 | int status) | ||
372 | { | ||
373 | struct tty_struct *tty = info->port.tty; | ||
374 | int num_bytes; | ||
375 | unsigned long flags; | ||
376 | |||
377 | flags = claim_dma_lock(); | ||
378 | disable_dma(dma); | ||
379 | clear_dma_ff(dma); | ||
380 | |||
381 | info->stat_flags &= ~ESP_STAT_DMA_RX; | ||
382 | num_bytes = dma_bytes - get_dma_residue(dma); | ||
383 | release_dma_lock(flags); | ||
384 | |||
385 | info->icount.rx += num_bytes; | ||
386 | |||
387 | if (num_bytes > 0) { | ||
388 | tty_insert_flip_string(tty, dma_buffer, num_bytes - 1); | ||
389 | |||
390 | status &= (0x1c & info->read_status_mask); | ||
391 | |||
392 | /* Is the status significant or do we throw the last byte ? */ | ||
393 | if (!(status & info->ignore_status_mask)) { | ||
394 | int statflag = 0; | ||
395 | |||
396 | if (status & 0x10) { | ||
397 | statflag = TTY_BREAK; | ||
398 | (info->icount.brk)++; | ||
399 | if (info->port.flags & ASYNC_SAK) | ||
400 | do_SAK(tty); | ||
401 | } else if (status & 0x08) { | ||
402 | statflag = TTY_FRAME; | ||
403 | info->icount.frame++; | ||
404 | } else if (status & 0x04) { | ||
405 | statflag = TTY_PARITY; | ||
406 | info->icount.parity++; | ||
407 | } | ||
408 | tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], | ||
409 | statflag); | ||
410 | } | ||
411 | tty_schedule_flip(tty); | ||
412 | } | ||
413 | |||
414 | if (dma_bytes != num_bytes) { | ||
415 | num_bytes = dma_bytes - num_bytes; | ||
416 | dma_bytes = 0; | ||
417 | receive_chars_dma(info, num_bytes); | ||
418 | } else | ||
419 | dma_bytes = 0; | ||
420 | } | ||
421 | |||
422 | /* Caller must hold info->lock */ | ||
423 | |||
424 | static inline void transmit_chars_pio(struct esp_struct *info, | ||
425 | int space_avail) | ||
426 | { | ||
427 | int i; | ||
428 | struct esp_pio_buffer *pio_buf; | ||
429 | |||
430 | pio_buf = get_pio_buffer(); | ||
431 | |||
432 | if (!pio_buf) | ||
433 | return; | ||
434 | |||
435 | while (space_avail && info->xmit_cnt) { | ||
436 | if (info->xmit_tail + space_avail <= ESP_XMIT_SIZE) { | ||
437 | memcpy(pio_buf->data, | ||
438 | &(info->xmit_buf[info->xmit_tail]), | ||
439 | space_avail); | ||
440 | } else { | ||
441 | i = ESP_XMIT_SIZE - info->xmit_tail; | ||
442 | memcpy(pio_buf->data, | ||
443 | &(info->xmit_buf[info->xmit_tail]), i); | ||
444 | memcpy(&(pio_buf->data[i]), info->xmit_buf, | ||
445 | space_avail - i); | ||
446 | } | ||
447 | |||
448 | info->xmit_cnt -= space_avail; | ||
449 | info->xmit_tail = (info->xmit_tail + space_avail) & | ||
450 | (ESP_XMIT_SIZE - 1); | ||
451 | |||
452 | for (i = 0; i < space_avail - 1; i += 2) { | ||
453 | outw(*((unsigned short *)(pio_buf->data + i)), | ||
454 | info->io_port + UART_ESI_TX); | ||
455 | } | ||
456 | |||
457 | if (space_avail & 0x0001) | ||
458 | serial_out(info, UART_ESI_TX, | ||
459 | pio_buf->data[space_avail - 1]); | ||
460 | |||
461 | if (info->xmit_cnt) { | ||
462 | serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); | ||
463 | serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL); | ||
464 | space_avail = serial_in(info, UART_ESI_STAT1) << 8; | ||
465 | space_avail |= serial_in(info, UART_ESI_STAT2); | ||
466 | |||
467 | if (space_avail > info->xmit_cnt) | ||
468 | space_avail = info->xmit_cnt; | ||
469 | } | ||
470 | } | ||
471 | |||
472 | if (info->xmit_cnt < WAKEUP_CHARS) { | ||
473 | if (info->port.tty) | ||
474 | tty_wakeup(info->port.tty); | ||
475 | |||
476 | #ifdef SERIAL_DEBUG_INTR | ||
477 | printk("THRE..."); | ||
478 | #endif | ||
479 | |||
480 | if (info->xmit_cnt <= 0) { | ||
481 | info->IER &= ~UART_IER_THRI; | ||
482 | serial_out(info, UART_ESI_CMD1, | ||
483 | ESI_SET_SRV_MASK); | ||
484 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
485 | } | ||
486 | } | ||
487 | |||
488 | release_pio_buffer(pio_buf); | ||
489 | } | ||
490 | |||
491 | /* Caller must hold info->lock */ | ||
492 | static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes) | ||
493 | { | ||
494 | dma_bytes = num_bytes; | ||
495 | |||
496 | if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) { | ||
497 | memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]), | ||
498 | dma_bytes); | ||
499 | } else { | ||
500 | int i = ESP_XMIT_SIZE - info->xmit_tail; | ||
501 | memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]), | ||
502 | i); | ||
503 | memcpy(&(dma_buffer[i]), info->xmit_buf, dma_bytes - i); | ||
504 | } | ||
505 | |||
506 | info->xmit_cnt -= dma_bytes; | ||
507 | info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1); | ||
508 | |||
509 | if (info->xmit_cnt < WAKEUP_CHARS) { | ||
510 | if (info->port.tty) | ||
511 | tty_wakeup(info->port.tty); | ||
512 | |||
513 | #ifdef SERIAL_DEBUG_INTR | ||
514 | printk("THRE..."); | ||
515 | #endif | ||
516 | |||
517 | if (info->xmit_cnt <= 0) { | ||
518 | info->IER &= ~UART_IER_THRI; | ||
519 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
520 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
521 | } | ||
522 | } | ||
523 | |||
524 | info->stat_flags |= ESP_STAT_DMA_TX; | ||
525 | |||
526 | program_isa_dma(dma, DMA_MODE_WRITE, isa_virt_to_bus(dma_buffer), | ||
527 | dma_bytes); | ||
528 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); | ||
529 | } | ||
530 | |||
531 | static inline void transmit_chars_dma_done(struct esp_struct *info) | ||
532 | { | ||
533 | int num_bytes; | ||
534 | unsigned long flags; | ||
535 | |||
536 | flags = claim_dma_lock(); | ||
537 | disable_dma(dma); | ||
538 | clear_dma_ff(dma); | ||
539 | |||
540 | num_bytes = dma_bytes - get_dma_residue(dma); | ||
541 | info->icount.tx += dma_bytes; | ||
542 | release_dma_lock(flags); | ||
543 | |||
544 | if (dma_bytes != num_bytes) { | ||
545 | dma_bytes -= num_bytes; | ||
546 | memmove(dma_buffer, dma_buffer + num_bytes, dma_bytes); | ||
547 | |||
548 | program_isa_dma(dma, DMA_MODE_WRITE, | ||
549 | isa_virt_to_bus(dma_buffer), dma_bytes); | ||
550 | |||
551 | serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX); | ||
552 | } else { | ||
553 | dma_bytes = 0; | ||
554 | info->stat_flags &= ~ESP_STAT_DMA_TX; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | static void check_modem_status(struct esp_struct *info) | ||
559 | { | ||
560 | int status; | ||
561 | |||
562 | serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); | ||
563 | status = serial_in(info, UART_ESI_STAT2); | ||
564 | |||
565 | if (status & UART_MSR_ANY_DELTA) { | ||
566 | /* update input line counters */ | ||
567 | if (status & UART_MSR_TERI) | ||
568 | info->icount.rng++; | ||
569 | if (status & UART_MSR_DDSR) | ||
570 | info->icount.dsr++; | ||
571 | if (status & UART_MSR_DDCD) | ||
572 | info->icount.dcd++; | ||
573 | if (status & UART_MSR_DCTS) | ||
574 | info->icount.cts++; | ||
575 | wake_up_interruptible(&info->port.delta_msr_wait); | ||
576 | } | ||
577 | |||
578 | if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { | ||
579 | #if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) | ||
580 | printk("ttys%d CD now %s...", info->line, | ||
581 | (status & UART_MSR_DCD) ? "on" : "off"); | ||
582 | #endif | ||
583 | if (status & UART_MSR_DCD) | ||
584 | wake_up_interruptible(&info->port.open_wait); | ||
585 | else { | ||
586 | #ifdef SERIAL_DEBUG_OPEN | ||
587 | printk("scheduling hangup..."); | ||
588 | #endif | ||
589 | tty_hangup(info->port.tty); | ||
590 | } | ||
591 | } | ||
592 | } | ||
593 | |||
594 | /* | ||
595 | * This is the serial driver's interrupt routine | ||
596 | */ | ||
597 | static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | ||
598 | { | ||
599 | struct esp_struct *info; | ||
600 | unsigned err_status; | ||
601 | unsigned int scratch; | ||
602 | |||
603 | #ifdef SERIAL_DEBUG_INTR | ||
604 | printk("rs_interrupt_single(%d)...", irq); | ||
605 | #endif | ||
606 | info = (struct esp_struct *)dev_id; | ||
607 | err_status = 0; | ||
608 | scratch = serial_in(info, UART_ESI_SID); | ||
609 | |||
610 | spin_lock(&info->lock); | ||
611 | |||
612 | if (!info->port.tty) { | ||
613 | spin_unlock(&info->lock); | ||
614 | return IRQ_NONE; | ||
615 | } | ||
616 | |||
617 | if (scratch & 0x04) { /* error */ | ||
618 | serial_out(info, UART_ESI_CMD1, ESI_GET_ERR_STAT); | ||
619 | err_status = serial_in(info, UART_ESI_STAT1); | ||
620 | serial_in(info, UART_ESI_STAT2); | ||
621 | |||
622 | if (err_status & 0x01) | ||
623 | info->stat_flags |= ESP_STAT_RX_TIMEOUT; | ||
624 | |||
625 | if (err_status & 0x20) /* UART status */ | ||
626 | check_modem_status(info); | ||
627 | |||
628 | if (err_status & 0x80) /* Start break */ | ||
629 | wake_up_interruptible(&info->break_wait); | ||
630 | } | ||
631 | |||
632 | if ((scratch & 0x88) || /* DMA completed or timed out */ | ||
633 | (err_status & 0x1c) /* receive error */) { | ||
634 | if (info->stat_flags & ESP_STAT_DMA_RX) | ||
635 | receive_chars_dma_done(info, err_status); | ||
636 | else if (info->stat_flags & ESP_STAT_DMA_TX) | ||
637 | transmit_chars_dma_done(info); | ||
638 | } | ||
639 | |||
640 | if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) && | ||
641 | ((scratch & 0x01) || (info->stat_flags & ESP_STAT_RX_TIMEOUT)) && | ||
642 | (info->IER & UART_IER_RDI)) { | ||
643 | int num_bytes; | ||
644 | |||
645 | serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); | ||
646 | serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL); | ||
647 | num_bytes = serial_in(info, UART_ESI_STAT1) << 8; | ||
648 | num_bytes |= serial_in(info, UART_ESI_STAT2); | ||
649 | |||
650 | num_bytes = tty_buffer_request_room(info->port.tty, num_bytes); | ||
651 | |||
652 | if (num_bytes) { | ||
653 | if (dma_bytes || | ||
654 | (info->stat_flags & ESP_STAT_USE_PIO) || | ||
655 | (num_bytes <= info->config.pio_threshold)) | ||
656 | receive_chars_pio(info, num_bytes); | ||
657 | else | ||
658 | receive_chars_dma(info, num_bytes); | ||
659 | } | ||
660 | } | ||
661 | |||
662 | if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) && | ||
663 | (scratch & 0x02) && (info->IER & UART_IER_THRI)) { | ||
664 | if ((info->xmit_cnt <= 0) || info->port.tty->stopped) { | ||
665 | info->IER &= ~UART_IER_THRI; | ||
666 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
667 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
668 | } else { | ||
669 | int num_bytes; | ||
670 | |||
671 | serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); | ||
672 | serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL); | ||
673 | num_bytes = serial_in(info, UART_ESI_STAT1) << 8; | ||
674 | num_bytes |= serial_in(info, UART_ESI_STAT2); | ||
675 | |||
676 | if (num_bytes > info->xmit_cnt) | ||
677 | num_bytes = info->xmit_cnt; | ||
678 | |||
679 | if (num_bytes) { | ||
680 | if (dma_bytes || | ||
681 | (info->stat_flags & ESP_STAT_USE_PIO) || | ||
682 | (num_bytes <= info->config.pio_threshold)) | ||
683 | transmit_chars_pio(info, num_bytes); | ||
684 | else | ||
685 | transmit_chars_dma(info, num_bytes); | ||
686 | } | ||
687 | } | ||
688 | } | ||
689 | |||
690 | info->last_active = jiffies; | ||
691 | |||
692 | #ifdef SERIAL_DEBUG_INTR | ||
693 | printk("end.\n"); | ||
694 | #endif | ||
695 | spin_unlock(&info->lock); | ||
696 | return IRQ_HANDLED; | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * ------------------------------------------------------------------- | ||
701 | * Here ends the serial interrupt routines. | ||
702 | * ------------------------------------------------------------------- | ||
703 | */ | ||
704 | |||
705 | /* | ||
706 | * --------------------------------------------------------------- | ||
707 | * Low level utility subroutines for the serial driver: routines to | ||
708 | * figure out the appropriate timeout for an interrupt chain, routines | ||
709 | * to initialize and startup a serial port, and routines to shutdown a | ||
710 | * serial port. Useful stuff like that. | ||
711 | * | ||
712 | * Caller should hold lock | ||
713 | * --------------------------------------------------------------- | ||
714 | */ | ||
715 | |||
716 | static void esp_basic_init(struct esp_struct *info) | ||
717 | { | ||
718 | /* put ESPC in enhanced mode */ | ||
719 | serial_out(info, UART_ESI_CMD1, ESI_SET_MODE); | ||
720 | |||
721 | if (info->stat_flags & ESP_STAT_NEVER_DMA) | ||
722 | serial_out(info, UART_ESI_CMD2, 0x01); | ||
723 | else | ||
724 | serial_out(info, UART_ESI_CMD2, 0x31); | ||
725 | |||
726 | /* disable interrupts for now */ | ||
727 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
728 | serial_out(info, UART_ESI_CMD2, 0x00); | ||
729 | |||
730 | /* set interrupt and DMA channel */ | ||
731 | serial_out(info, UART_ESI_CMD1, ESI_SET_IRQ); | ||
732 | |||
733 | if (info->stat_flags & ESP_STAT_NEVER_DMA) | ||
734 | serial_out(info, UART_ESI_CMD2, 0x01); | ||
735 | else | ||
736 | serial_out(info, UART_ESI_CMD2, (dma << 4) | 0x01); | ||
737 | |||
738 | serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ); | ||
739 | |||
740 | if (info->line % 8) /* secondary port */ | ||
741 | serial_out(info, UART_ESI_CMD2, 0x0d); /* shared */ | ||
742 | else if (info->irq == 9) | ||
743 | serial_out(info, UART_ESI_CMD2, 0x02); | ||
744 | else | ||
745 | serial_out(info, UART_ESI_CMD2, info->irq); | ||
746 | |||
747 | /* set error status mask (check this) */ | ||
748 | serial_out(info, UART_ESI_CMD1, ESI_SET_ERR_MASK); | ||
749 | |||
750 | if (info->stat_flags & ESP_STAT_NEVER_DMA) | ||
751 | serial_out(info, UART_ESI_CMD2, 0xa1); | ||
752 | else | ||
753 | serial_out(info, UART_ESI_CMD2, 0xbd); | ||
754 | |||
755 | serial_out(info, UART_ESI_CMD2, 0x00); | ||
756 | |||
757 | /* set DMA timeout */ | ||
758 | serial_out(info, UART_ESI_CMD1, ESI_SET_DMA_TMOUT); | ||
759 | serial_out(info, UART_ESI_CMD2, 0xff); | ||
760 | |||
761 | /* set FIFO trigger levels */ | ||
762 | serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER); | ||
763 | serial_out(info, UART_ESI_CMD2, info->config.rx_trigger >> 8); | ||
764 | serial_out(info, UART_ESI_CMD2, info->config.rx_trigger); | ||
765 | serial_out(info, UART_ESI_CMD2, info->config.tx_trigger >> 8); | ||
766 | serial_out(info, UART_ESI_CMD2, info->config.tx_trigger); | ||
767 | |||
768 | /* Set clock scaling and wait states */ | ||
769 | serial_out(info, UART_ESI_CMD1, ESI_SET_PRESCALAR); | ||
770 | serial_out(info, UART_ESI_CMD2, 0x04 | ESPC_SCALE); | ||
771 | |||
772 | /* set reinterrupt pacing */ | ||
773 | serial_out(info, UART_ESI_CMD1, ESI_SET_REINTR); | ||
774 | serial_out(info, UART_ESI_CMD2, 0xff); | ||
775 | } | ||
776 | |||
777 | static int startup(struct esp_struct *info) | ||
778 | { | ||
779 | unsigned long flags; | ||
780 | int retval = 0; | ||
781 | unsigned int num_chars; | ||
782 | |||
783 | spin_lock_irqsave(&info->lock, flags); | ||
784 | |||
785 | if (info->port.flags & ASYNC_INITIALIZED) | ||
786 | goto out; | ||
787 | |||
788 | if (!info->xmit_buf) { | ||
789 | info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_ATOMIC); | ||
790 | retval = -ENOMEM; | ||
791 | if (!info->xmit_buf) | ||
792 | goto out; | ||
793 | } | ||
794 | |||
795 | #ifdef SERIAL_DEBUG_OPEN | ||
796 | printk(KERN_DEBUG "starting up ttys%d (irq %d)...", | ||
797 | info->line, info->irq); | ||
798 | #endif | ||
799 | |||
800 | /* Flush the RX buffer. Using the ESI flush command may cause */ | ||
801 | /* wild interrupts, so read all the data instead. */ | ||
802 | |||
803 | serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); | ||
804 | serial_out(info, UART_ESI_CMD1, ESI_GET_RX_AVAIL); | ||
805 | num_chars = serial_in(info, UART_ESI_STAT1) << 8; | ||
806 | num_chars |= serial_in(info, UART_ESI_STAT2); | ||
807 | |||
808 | while (num_chars > 1) { | ||
809 | inw(info->io_port + UART_ESI_RX); | ||
810 | num_chars -= 2; | ||
811 | } | ||
812 | |||
813 | if (num_chars) | ||
814 | serial_in(info, UART_ESI_RX); | ||
815 | |||
816 | /* set receive character timeout */ | ||
817 | serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT); | ||
818 | serial_out(info, UART_ESI_CMD2, info->config.rx_timeout); | ||
819 | |||
820 | /* clear all flags except the "never DMA" flag */ | ||
821 | info->stat_flags &= ESP_STAT_NEVER_DMA; | ||
822 | |||
823 | if (info->stat_flags & ESP_STAT_NEVER_DMA) | ||
824 | info->stat_flags |= ESP_STAT_USE_PIO; | ||
825 | |||
826 | spin_unlock_irqrestore(&info->lock, flags); | ||
827 | |||
828 | /* | ||
829 | * Allocate the IRQ | ||
830 | */ | ||
831 | |||
832 | retval = request_irq(info->irq, rs_interrupt_single, IRQF_SHARED, | ||
833 | "esp serial", info); | ||
834 | |||
835 | if (retval) { | ||
836 | if (capable(CAP_SYS_ADMIN)) { | ||
837 | if (info->port.tty) | ||
838 | set_bit(TTY_IO_ERROR, | ||
839 | &info->port.tty->flags); | ||
840 | retval = 0; | ||
841 | } | ||
842 | goto out_unlocked; | ||
843 | } | ||
844 | |||
845 | if (!(info->stat_flags & ESP_STAT_USE_PIO) && !dma_buffer) { | ||
846 | dma_buffer = (char *)__get_dma_pages( | ||
847 | GFP_KERNEL, get_order(DMA_BUFFER_SZ)); | ||
848 | |||
849 | /* use PIO mode if DMA buf/chan cannot be allocated */ | ||
850 | if (!dma_buffer) | ||
851 | info->stat_flags |= ESP_STAT_USE_PIO; | ||
852 | else if (request_dma(dma, "esp serial")) { | ||
853 | free_pages((unsigned long)dma_buffer, | ||
854 | get_order(DMA_BUFFER_SZ)); | ||
855 | dma_buffer = NULL; | ||
856 | info->stat_flags |= ESP_STAT_USE_PIO; | ||
857 | } | ||
858 | |||
859 | } | ||
860 | |||
861 | info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; | ||
862 | |||
863 | spin_lock_irqsave(&info->lock, flags); | ||
864 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | ||
865 | serial_out(info, UART_ESI_CMD2, UART_MCR); | ||
866 | serial_out(info, UART_ESI_CMD2, info->MCR); | ||
867 | |||
868 | /* | ||
869 | * Finally, enable interrupts | ||
870 | */ | ||
871 | /* info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; */ | ||
872 | info->IER = UART_IER_RLSI | UART_IER_RDI | UART_IER_DMA_TMOUT | | ||
873 | UART_IER_DMA_TC; | ||
874 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
875 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
876 | |||
877 | if (info->port.tty) | ||
878 | clear_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
879 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
880 | spin_unlock_irqrestore(&info->lock, flags); | ||
881 | |||
882 | /* | ||
883 | * Set up the tty->alt_speed kludge | ||
884 | */ | ||
885 | if (info->port.tty) { | ||
886 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | ||
887 | info->port.tty->alt_speed = 57600; | ||
888 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | ||
889 | info->port.tty->alt_speed = 115200; | ||
890 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | ||
891 | info->port.tty->alt_speed = 230400; | ||
892 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | ||
893 | info->port.tty->alt_speed = 460800; | ||
894 | } | ||
895 | |||
896 | /* | ||
897 | * set the speed of the serial port | ||
898 | */ | ||
899 | change_speed(info); | ||
900 | info->port.flags |= ASYNC_INITIALIZED; | ||
901 | return 0; | ||
902 | |||
903 | out: | ||
904 | spin_unlock_irqrestore(&info->lock, flags); | ||
905 | out_unlocked: | ||
906 | return retval; | ||
907 | } | ||
908 | |||
909 | /* | ||
910 | * This routine will shutdown a serial port; interrupts are disabled, and | ||
911 | * DTR is dropped if the hangup on close termio flag is on. | ||
912 | */ | ||
913 | static void shutdown(struct esp_struct *info) | ||
914 | { | ||
915 | unsigned long flags, f; | ||
916 | |||
917 | if (!(info->port.flags & ASYNC_INITIALIZED)) | ||
918 | return; | ||
919 | |||
920 | #ifdef SERIAL_DEBUG_OPEN | ||
921 | printk("Shutting down serial port %d (irq %d)....", info->line, | ||
922 | info->irq); | ||
923 | #endif | ||
924 | |||
925 | spin_lock_irqsave(&info->lock, flags); | ||
926 | /* | ||
927 | * clear delta_msr_wait queue to avoid mem leaks: we may free the irq | ||
928 | * here so the queue might never be waken up | ||
929 | */ | ||
930 | wake_up_interruptible(&info->port.delta_msr_wait); | ||
931 | wake_up_interruptible(&info->break_wait); | ||
932 | |||
933 | /* stop a DMA transfer on the port being closed */ | ||
934 | /* DMA lock is higher priority always */ | ||
935 | if (info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) { | ||
936 | f = claim_dma_lock(); | ||
937 | disable_dma(dma); | ||
938 | clear_dma_ff(dma); | ||
939 | release_dma_lock(f); | ||
940 | |||
941 | dma_bytes = 0; | ||
942 | } | ||
943 | |||
944 | /* | ||
945 | * Free the IRQ | ||
946 | */ | ||
947 | free_irq(info->irq, info); | ||
948 | |||
949 | if (dma_buffer) { | ||
950 | struct esp_struct *current_port = ports; | ||
951 | |||
952 | while (current_port) { | ||
953 | if ((current_port != info) && | ||
954 | (current_port->port.flags & ASYNC_INITIALIZED)) | ||
955 | break; | ||
956 | |||
957 | current_port = current_port->next_port; | ||
958 | } | ||
959 | |||
960 | if (!current_port) { | ||
961 | free_dma(dma); | ||
962 | free_pages((unsigned long)dma_buffer, | ||
963 | get_order(DMA_BUFFER_SZ)); | ||
964 | dma_buffer = NULL; | ||
965 | } | ||
966 | } | ||
967 | |||
968 | if (info->xmit_buf) { | ||
969 | free_page((unsigned long) info->xmit_buf); | ||
970 | info->xmit_buf = NULL; | ||
971 | } | ||
972 | |||
973 | info->IER = 0; | ||
974 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
975 | serial_out(info, UART_ESI_CMD2, 0x00); | ||
976 | |||
977 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) | ||
978 | info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); | ||
979 | |||
980 | info->MCR &= ~UART_MCR_OUT2; | ||
981 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | ||
982 | serial_out(info, UART_ESI_CMD2, UART_MCR); | ||
983 | serial_out(info, UART_ESI_CMD2, info->MCR); | ||
984 | |||
985 | if (info->port.tty) | ||
986 | set_bit(TTY_IO_ERROR, &info->port.tty->flags); | ||
987 | |||
988 | info->port.flags &= ~ASYNC_INITIALIZED; | ||
989 | spin_unlock_irqrestore(&info->lock, flags); | ||
990 | } | ||
991 | |||
992 | /* | ||
993 | * This routine is called to set the UART divisor registers to match | ||
994 | * the specified baud rate for a serial port. | ||
995 | */ | ||
996 | static void change_speed(struct esp_struct *info) | ||
997 | { | ||
998 | unsigned short port; | ||
999 | int quot = 0; | ||
1000 | unsigned cflag, cval; | ||
1001 | int baud, bits; | ||
1002 | unsigned char flow1 = 0, flow2 = 0; | ||
1003 | unsigned long flags; | ||
1004 | |||
1005 | if (!info->port.tty || !info->port.tty->termios) | ||
1006 | return; | ||
1007 | cflag = info->port.tty->termios->c_cflag; | ||
1008 | port = info->io_port; | ||
1009 | |||
1010 | /* byte size and parity */ | ||
1011 | switch (cflag & CSIZE) { | ||
1012 | case CS5: cval = 0x00; bits = 7; break; | ||
1013 | case CS6: cval = 0x01; bits = 8; break; | ||
1014 | case CS7: cval = 0x02; bits = 9; break; | ||
1015 | case CS8: cval = 0x03; bits = 10; break; | ||
1016 | default: cval = 0x00; bits = 7; break; | ||
1017 | } | ||
1018 | if (cflag & CSTOPB) { | ||
1019 | cval |= 0x04; | ||
1020 | bits++; | ||
1021 | } | ||
1022 | if (cflag & PARENB) { | ||
1023 | cval |= UART_LCR_PARITY; | ||
1024 | bits++; | ||
1025 | } | ||
1026 | if (!(cflag & PARODD)) | ||
1027 | cval |= UART_LCR_EPAR; | ||
1028 | #ifdef CMSPAR | ||
1029 | if (cflag & CMSPAR) | ||
1030 | cval |= UART_LCR_SPAR; | ||
1031 | #endif | ||
1032 | baud = tty_get_baud_rate(info->port.tty); | ||
1033 | if (baud == 38400 && | ||
1034 | ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) | ||
1035 | quot = info->custom_divisor; | ||
1036 | else { | ||
1037 | if (baud == 134) /* Special case since 134 is really 134.5 */ | ||
1038 | quot = (2*BASE_BAUD / 269); | ||
1039 | else if (baud) | ||
1040 | quot = BASE_BAUD / baud; | ||
1041 | } | ||
1042 | /* If the quotient is ever zero, default to 9600 bps */ | ||
1043 | if (!quot) | ||
1044 | quot = BASE_BAUD / 9600; | ||
1045 | |||
1046 | if (baud) { | ||
1047 | /* Actual rate */ | ||
1048 | baud = BASE_BAUD/quot; | ||
1049 | tty_encode_baud_rate(info->port.tty, baud, baud); | ||
1050 | } | ||
1051 | info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50); | ||
1052 | |||
1053 | /* CTS flow control flag and modem status interrupts */ | ||
1054 | /* info->IER &= ~UART_IER_MSI; */ | ||
1055 | if (cflag & CRTSCTS) { | ||
1056 | info->port.flags |= ASYNC_CTS_FLOW; | ||
1057 | /* info->IER |= UART_IER_MSI; */ | ||
1058 | flow1 = 0x04; | ||
1059 | flow2 = 0x10; | ||
1060 | } else | ||
1061 | info->port.flags &= ~ASYNC_CTS_FLOW; | ||
1062 | if (cflag & CLOCAL) | ||
1063 | info->port.flags &= ~ASYNC_CHECK_CD; | ||
1064 | else | ||
1065 | info->port.flags |= ASYNC_CHECK_CD; | ||
1066 | |||
1067 | /* | ||
1068 | * Set up parity check flag | ||
1069 | */ | ||
1070 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | ||
1071 | if (I_INPCK(info->port.tty)) | ||
1072 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | ||
1073 | if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) | ||
1074 | info->read_status_mask |= UART_LSR_BI; | ||
1075 | |||
1076 | info->ignore_status_mask = 0; | ||
1077 | #if 0 | ||
1078 | /* This should be safe, but for some broken bits of hardware... */ | ||
1079 | if (I_IGNPAR(info->port.tty)) { | ||
1080 | info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; | ||
1081 | info->read_status_mask |= UART_LSR_PE | UART_LSR_FE; | ||
1082 | } | ||
1083 | #endif | ||
1084 | if (I_IGNBRK(info->port.tty)) { | ||
1085 | info->ignore_status_mask |= UART_LSR_BI; | ||
1086 | info->read_status_mask |= UART_LSR_BI; | ||
1087 | /* | ||
1088 | * If we're ignore parity and break indicators, ignore | ||
1089 | * overruns too. (For real raw support). | ||
1090 | */ | ||
1091 | if (I_IGNPAR(info->port.tty)) { | ||
1092 | info->ignore_status_mask |= UART_LSR_OE | \ | ||
1093 | UART_LSR_PE | UART_LSR_FE; | ||
1094 | info->read_status_mask |= UART_LSR_OE | \ | ||
1095 | UART_LSR_PE | UART_LSR_FE; | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1099 | if (I_IXOFF(info->port.tty)) | ||
1100 | flow1 |= 0x81; | ||
1101 | |||
1102 | spin_lock_irqsave(&info->lock, flags); | ||
1103 | /* set baud */ | ||
1104 | serial_out(info, UART_ESI_CMD1, ESI_SET_BAUD); | ||
1105 | serial_out(info, UART_ESI_CMD2, quot >> 8); | ||
1106 | serial_out(info, UART_ESI_CMD2, quot & 0xff); | ||
1107 | |||
1108 | /* set data bits, parity, etc. */ | ||
1109 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | ||
1110 | serial_out(info, UART_ESI_CMD2, UART_LCR); | ||
1111 | serial_out(info, UART_ESI_CMD2, cval); | ||
1112 | |||
1113 | /* Enable flow control */ | ||
1114 | serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CNTL); | ||
1115 | serial_out(info, UART_ESI_CMD2, flow1); | ||
1116 | serial_out(info, UART_ESI_CMD2, flow2); | ||
1117 | |||
1118 | /* set flow control characters (XON/XOFF only) */ | ||
1119 | if (I_IXOFF(info->port.tty)) { | ||
1120 | serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CHARS); | ||
1121 | serial_out(info, UART_ESI_CMD2, START_CHAR(info->port.tty)); | ||
1122 | serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->port.tty)); | ||
1123 | serial_out(info, UART_ESI_CMD2, 0x10); | ||
1124 | serial_out(info, UART_ESI_CMD2, 0x21); | ||
1125 | switch (cflag & CSIZE) { | ||
1126 | case CS5: | ||
1127 | serial_out(info, UART_ESI_CMD2, 0x1f); | ||
1128 | break; | ||
1129 | case CS6: | ||
1130 | serial_out(info, UART_ESI_CMD2, 0x3f); | ||
1131 | break; | ||
1132 | case CS7: | ||
1133 | case CS8: | ||
1134 | serial_out(info, UART_ESI_CMD2, 0x7f); | ||
1135 | break; | ||
1136 | default: | ||
1137 | serial_out(info, UART_ESI_CMD2, 0xff); | ||
1138 | break; | ||
1139 | } | ||
1140 | } | ||
1141 | |||
1142 | /* Set high/low water */ | ||
1143 | serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL); | ||
1144 | serial_out(info, UART_ESI_CMD2, info->config.flow_off >> 8); | ||
1145 | serial_out(info, UART_ESI_CMD2, info->config.flow_off); | ||
1146 | serial_out(info, UART_ESI_CMD2, info->config.flow_on >> 8); | ||
1147 | serial_out(info, UART_ESI_CMD2, info->config.flow_on); | ||
1148 | |||
1149 | spin_unlock_irqrestore(&info->lock, flags); | ||
1150 | } | ||
1151 | |||
1152 | static int rs_put_char(struct tty_struct *tty, unsigned char ch) | ||
1153 | { | ||
1154 | struct esp_struct *info = tty->driver_data; | ||
1155 | unsigned long flags; | ||
1156 | int ret = 0; | ||
1157 | |||
1158 | if (serial_paranoia_check(info, tty->name, "rs_put_char")) | ||
1159 | return 0; | ||
1160 | |||
1161 | if (!info->xmit_buf) | ||
1162 | return 0; | ||
1163 | |||
1164 | spin_lock_irqsave(&info->lock, flags); | ||
1165 | if (info->xmit_cnt < ESP_XMIT_SIZE - 1) { | ||
1166 | info->xmit_buf[info->xmit_head++] = ch; | ||
1167 | info->xmit_head &= ESP_XMIT_SIZE-1; | ||
1168 | info->xmit_cnt++; | ||
1169 | ret = 1; | ||
1170 | } | ||
1171 | spin_unlock_irqrestore(&info->lock, flags); | ||
1172 | return ret; | ||
1173 | } | ||
1174 | |||
1175 | static void rs_flush_chars(struct tty_struct *tty) | ||
1176 | { | ||
1177 | struct esp_struct *info = tty->driver_data; | ||
1178 | unsigned long flags; | ||
1179 | |||
1180 | if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) | ||
1181 | return; | ||
1182 | |||
1183 | spin_lock_irqsave(&info->lock, flags); | ||
1184 | |||
1185 | if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf) | ||
1186 | goto out; | ||
1187 | |||
1188 | if (!(info->IER & UART_IER_THRI)) { | ||
1189 | info->IER |= UART_IER_THRI; | ||
1190 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
1191 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
1192 | } | ||
1193 | out: | ||
1194 | spin_unlock_irqrestore(&info->lock, flags); | ||
1195 | } | ||
1196 | |||
1197 | static int rs_write(struct tty_struct *tty, | ||
1198 | const unsigned char *buf, int count) | ||
1199 | { | ||
1200 | int c, t, ret = 0; | ||
1201 | struct esp_struct *info = tty->driver_data; | ||
1202 | unsigned long flags; | ||
1203 | |||
1204 | if (serial_paranoia_check(info, tty->name, "rs_write")) | ||
1205 | return 0; | ||
1206 | |||
1207 | if (!info->xmit_buf) | ||
1208 | return 0; | ||
1209 | |||
1210 | while (1) { | ||
1211 | /* Thanks to R. Wolff for suggesting how to do this with */ | ||
1212 | /* interrupts enabled */ | ||
1213 | |||
1214 | c = count; | ||
1215 | t = ESP_XMIT_SIZE - info->xmit_cnt - 1; | ||
1216 | |||
1217 | if (t < c) | ||
1218 | c = t; | ||
1219 | |||
1220 | t = ESP_XMIT_SIZE - info->xmit_head; | ||
1221 | |||
1222 | if (t < c) | ||
1223 | c = t; | ||
1224 | |||
1225 | if (c <= 0) | ||
1226 | break; | ||
1227 | |||
1228 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | ||
1229 | |||
1230 | info->xmit_head = (info->xmit_head + c) & (ESP_XMIT_SIZE-1); | ||
1231 | info->xmit_cnt += c; | ||
1232 | buf += c; | ||
1233 | count -= c; | ||
1234 | ret += c; | ||
1235 | } | ||
1236 | |||
1237 | spin_lock_irqsave(&info->lock, flags); | ||
1238 | |||
1239 | if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) { | ||
1240 | info->IER |= UART_IER_THRI; | ||
1241 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
1242 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
1243 | } | ||
1244 | |||
1245 | spin_unlock_irqrestore(&info->lock, flags); | ||
1246 | return ret; | ||
1247 | } | ||
1248 | |||
1249 | static int rs_write_room(struct tty_struct *tty) | ||
1250 | { | ||
1251 | struct esp_struct *info = tty->driver_data; | ||
1252 | int ret; | ||
1253 | unsigned long flags; | ||
1254 | |||
1255 | if (serial_paranoia_check(info, tty->name, "rs_write_room")) | ||
1256 | return 0; | ||
1257 | |||
1258 | spin_lock_irqsave(&info->lock, flags); | ||
1259 | |||
1260 | ret = ESP_XMIT_SIZE - info->xmit_cnt - 1; | ||
1261 | if (ret < 0) | ||
1262 | ret = 0; | ||
1263 | spin_unlock_irqrestore(&info->lock, flags); | ||
1264 | return ret; | ||
1265 | } | ||
1266 | |||
1267 | static int rs_chars_in_buffer(struct tty_struct *tty) | ||
1268 | { | ||
1269 | struct esp_struct *info = tty->driver_data; | ||
1270 | |||
1271 | if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) | ||
1272 | return 0; | ||
1273 | return info->xmit_cnt; | ||
1274 | } | ||
1275 | |||
1276 | static void rs_flush_buffer(struct tty_struct *tty) | ||
1277 | { | ||
1278 | struct esp_struct *info = tty->driver_data; | ||
1279 | unsigned long flags; | ||
1280 | |||
1281 | if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) | ||
1282 | return; | ||
1283 | spin_lock_irqsave(&info->lock, flags); | ||
1284 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
1285 | spin_unlock_irqrestore(&info->lock, flags); | ||
1286 | tty_wakeup(tty); | ||
1287 | } | ||
1288 | |||
1289 | /* | ||
1290 | * ------------------------------------------------------------ | ||
1291 | * rs_throttle() | ||
1292 | * | ||
1293 | * This routine is called by the upper-layer tty layer to signal that | ||
1294 | * incoming characters should be throttled. | ||
1295 | * ------------------------------------------------------------ | ||
1296 | */ | ||
1297 | static void rs_throttle(struct tty_struct *tty) | ||
1298 | { | ||
1299 | struct esp_struct *info = tty->driver_data; | ||
1300 | unsigned long flags; | ||
1301 | #ifdef SERIAL_DEBUG_THROTTLE | ||
1302 | char buf[64]; | ||
1303 | |||
1304 | printk("throttle %s: %d....\n", tty_name(tty, buf), | ||
1305 | tty_chars_in_buffer(tty)); | ||
1306 | #endif | ||
1307 | |||
1308 | if (serial_paranoia_check(info, tty->name, "rs_throttle")) | ||
1309 | return; | ||
1310 | |||
1311 | spin_lock_irqsave(&info->lock, flags); | ||
1312 | info->IER &= ~UART_IER_RDI; | ||
1313 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
1314 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
1315 | serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT); | ||
1316 | serial_out(info, UART_ESI_CMD2, 0x00); | ||
1317 | spin_unlock_irqrestore(&info->lock, flags); | ||
1318 | } | ||
1319 | |||
1320 | static void rs_unthrottle(struct tty_struct *tty) | ||
1321 | { | ||
1322 | struct esp_struct *info = tty->driver_data; | ||
1323 | unsigned long flags; | ||
1324 | #ifdef SERIAL_DEBUG_THROTTLE | ||
1325 | char buf[64]; | ||
1326 | |||
1327 | printk(KERN_DEBUG "unthrottle %s: %d....\n", tty_name(tty, buf), | ||
1328 | tty_chars_in_buffer(tty)); | ||
1329 | #endif | ||
1330 | |||
1331 | if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) | ||
1332 | return; | ||
1333 | |||
1334 | spin_lock_irqsave(&info->lock, flags); | ||
1335 | info->IER |= UART_IER_RDI; | ||
1336 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
1337 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
1338 | serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT); | ||
1339 | serial_out(info, UART_ESI_CMD2, info->config.rx_timeout); | ||
1340 | spin_unlock_irqrestore(&info->lock, flags); | ||
1341 | } | ||
1342 | |||
1343 | /* | ||
1344 | * ------------------------------------------------------------ | ||
1345 | * rs_ioctl() and friends | ||
1346 | * ------------------------------------------------------------ | ||
1347 | */ | ||
1348 | |||
1349 | static int get_serial_info(struct esp_struct *info, | ||
1350 | struct serial_struct __user *retinfo) | ||
1351 | { | ||
1352 | struct serial_struct tmp; | ||
1353 | |||
1354 | lock_kernel(); | ||
1355 | memset(&tmp, 0, sizeof(tmp)); | ||
1356 | tmp.type = PORT_16550A; | ||
1357 | tmp.line = info->line; | ||
1358 | tmp.port = info->io_port; | ||
1359 | tmp.irq = info->irq; | ||
1360 | tmp.flags = info->port.flags; | ||
1361 | tmp.xmit_fifo_size = 1024; | ||
1362 | tmp.baud_base = BASE_BAUD; | ||
1363 | tmp.close_delay = info->close_delay; | ||
1364 | tmp.closing_wait = info->closing_wait; | ||
1365 | tmp.custom_divisor = info->custom_divisor; | ||
1366 | tmp.hub6 = 0; | ||
1367 | unlock_kernel(); | ||
1368 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
1369 | return -EFAULT; | ||
1370 | return 0; | ||
1371 | } | ||
1372 | |||
1373 | static int get_esp_config(struct esp_struct *info, | ||
1374 | struct hayes_esp_config __user *retinfo) | ||
1375 | { | ||
1376 | struct hayes_esp_config tmp; | ||
1377 | |||
1378 | if (!retinfo) | ||
1379 | return -EFAULT; | ||
1380 | |||
1381 | memset(&tmp, 0, sizeof(tmp)); | ||
1382 | lock_kernel(); | ||
1383 | tmp.rx_timeout = info->config.rx_timeout; | ||
1384 | tmp.rx_trigger = info->config.rx_trigger; | ||
1385 | tmp.tx_trigger = info->config.tx_trigger; | ||
1386 | tmp.flow_off = info->config.flow_off; | ||
1387 | tmp.flow_on = info->config.flow_on; | ||
1388 | tmp.pio_threshold = info->config.pio_threshold; | ||
1389 | tmp.dma_channel = (info->stat_flags & ESP_STAT_NEVER_DMA ? 0 : dma); | ||
1390 | unlock_kernel(); | ||
1391 | |||
1392 | return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; | ||
1393 | } | ||
1394 | |||
1395 | static int set_serial_info(struct esp_struct *info, | ||
1396 | struct serial_struct __user *new_info) | ||
1397 | { | ||
1398 | struct serial_struct new_serial; | ||
1399 | struct esp_struct old_info; | ||
1400 | unsigned int change_irq; | ||
1401 | int retval = 0; | ||
1402 | struct esp_struct *current_async; | ||
1403 | |||
1404 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) | ||
1405 | return -EFAULT; | ||
1406 | old_info = *info; | ||
1407 | |||
1408 | if ((new_serial.type != PORT_16550A) || | ||
1409 | (new_serial.hub6) || | ||
1410 | (info->io_port != new_serial.port) || | ||
1411 | (new_serial.baud_base != BASE_BAUD) || | ||
1412 | (new_serial.irq > 15) || | ||
1413 | (new_serial.irq < 2) || | ||
1414 | (new_serial.irq == 6) || | ||
1415 | (new_serial.irq == 8) || | ||
1416 | (new_serial.irq == 13)) | ||
1417 | return -EINVAL; | ||
1418 | |||
1419 | change_irq = new_serial.irq != info->irq; | ||
1420 | |||
1421 | if (change_irq && (info->line % 8)) | ||
1422 | return -EINVAL; | ||
1423 | |||
1424 | if (!capable(CAP_SYS_ADMIN)) { | ||
1425 | if (change_irq || | ||
1426 | (new_serial.close_delay != info->close_delay) || | ||
1427 | ((new_serial.flags & ~ASYNC_USR_MASK) != | ||
1428 | (info->port.flags & ~ASYNC_USR_MASK))) | ||
1429 | return -EPERM; | ||
1430 | info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) | | ||
1431 | (new_serial.flags & ASYNC_USR_MASK)); | ||
1432 | info->custom_divisor = new_serial.custom_divisor; | ||
1433 | } else { | ||
1434 | if (new_serial.irq == 2) | ||
1435 | new_serial.irq = 9; | ||
1436 | |||
1437 | if (change_irq) { | ||
1438 | current_async = ports; | ||
1439 | |||
1440 | while (current_async) { | ||
1441 | if ((current_async->line >= info->line) && | ||
1442 | (current_async->line < (info->line + 8))) { | ||
1443 | if (current_async == info) { | ||
1444 | if (current_async->port.count > 1) | ||
1445 | return -EBUSY; | ||
1446 | } else if (current_async->port.count) | ||
1447 | return -EBUSY; | ||
1448 | } | ||
1449 | |||
1450 | current_async = current_async->next_port; | ||
1451 | } | ||
1452 | } | ||
1453 | |||
1454 | /* | ||
1455 | * OK, past this point, all the error checking has been done. | ||
1456 | * At this point, we start making changes..... | ||
1457 | */ | ||
1458 | |||
1459 | info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) | | ||
1460 | (new_serial.flags & ASYNC_FLAGS)); | ||
1461 | info->custom_divisor = new_serial.custom_divisor; | ||
1462 | info->close_delay = new_serial.close_delay * HZ/100; | ||
1463 | info->closing_wait = new_serial.closing_wait * HZ/100; | ||
1464 | |||
1465 | if (change_irq) { | ||
1466 | /* | ||
1467 | * We need to shutdown the serial port at the old | ||
1468 | * port/irq combination. | ||
1469 | */ | ||
1470 | shutdown(info); | ||
1471 | |||
1472 | current_async = ports; | ||
1473 | |||
1474 | while (current_async) { | ||
1475 | if ((current_async->line >= info->line) && | ||
1476 | (current_async->line < (info->line + 8))) | ||
1477 | current_async->irq = new_serial.irq; | ||
1478 | |||
1479 | current_async = current_async->next_port; | ||
1480 | } | ||
1481 | |||
1482 | serial_out(info, UART_ESI_CMD1, ESI_SET_ENH_IRQ); | ||
1483 | if (info->irq == 9) | ||
1484 | serial_out(info, UART_ESI_CMD2, 0x02); | ||
1485 | else | ||
1486 | serial_out(info, UART_ESI_CMD2, info->irq); | ||
1487 | } | ||
1488 | } | ||
1489 | |||
1490 | if (info->port.flags & ASYNC_INITIALIZED) { | ||
1491 | if (((old_info.port.flags & ASYNC_SPD_MASK) != | ||
1492 | (info->port.flags & ASYNC_SPD_MASK)) || | ||
1493 | (old_info.custom_divisor != info->custom_divisor)) { | ||
1494 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | ||
1495 | info->port.tty->alt_speed = 57600; | ||
1496 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | ||
1497 | info->port.tty->alt_speed = 115200; | ||
1498 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | ||
1499 | info->port.tty->alt_speed = 230400; | ||
1500 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | ||
1501 | info->port.tty->alt_speed = 460800; | ||
1502 | change_speed(info); | ||
1503 | } | ||
1504 | } else | ||
1505 | retval = startup(info); | ||
1506 | |||
1507 | return retval; | ||
1508 | } | ||
1509 | |||
1510 | static int set_esp_config(struct esp_struct *info, | ||
1511 | struct hayes_esp_config __user *new_info) | ||
1512 | { | ||
1513 | struct hayes_esp_config new_config; | ||
1514 | unsigned int change_dma; | ||
1515 | int retval = 0; | ||
1516 | struct esp_struct *current_async; | ||
1517 | unsigned long flags; | ||
1518 | |||
1519 | /* Perhaps a non-sysadmin user should be able to do some of these */ | ||
1520 | /* operations. I haven't decided yet. */ | ||
1521 | |||
1522 | if (!capable(CAP_SYS_ADMIN)) | ||
1523 | return -EPERM; | ||
1524 | |||
1525 | if (copy_from_user(&new_config, new_info, sizeof(new_config))) | ||
1526 | return -EFAULT; | ||
1527 | |||
1528 | if ((new_config.flow_on >= new_config.flow_off) || | ||
1529 | (new_config.rx_trigger < 1) || | ||
1530 | (new_config.tx_trigger < 1) || | ||
1531 | (new_config.flow_off < 1) || | ||
1532 | (new_config.flow_on < 1) || | ||
1533 | (new_config.rx_trigger > 1023) || | ||
1534 | (new_config.tx_trigger > 1023) || | ||
1535 | (new_config.flow_off > 1023) || | ||
1536 | (new_config.flow_on > 1023) || | ||
1537 | (new_config.pio_threshold < 0) || | ||
1538 | (new_config.pio_threshold > 1024)) | ||
1539 | return -EINVAL; | ||
1540 | |||
1541 | if ((new_config.dma_channel != 1) && (new_config.dma_channel != 3)) | ||
1542 | new_config.dma_channel = 0; | ||
1543 | |||
1544 | if (info->stat_flags & ESP_STAT_NEVER_DMA) | ||
1545 | change_dma = new_config.dma_channel; | ||
1546 | else | ||
1547 | change_dma = (new_config.dma_channel != dma); | ||
1548 | |||
1549 | if (change_dma) { | ||
1550 | if (new_config.dma_channel) { | ||
1551 | /* PIO mode to DMA mode transition OR */ | ||
1552 | /* change current DMA channel */ | ||
1553 | current_async = ports; | ||
1554 | |||
1555 | while (current_async) { | ||
1556 | if (current_async == info) { | ||
1557 | if (current_async->port.count > 1) | ||
1558 | return -EBUSY; | ||
1559 | } else if (current_async->port.count) | ||
1560 | return -EBUSY; | ||
1561 | |||
1562 | current_async = current_async->next_port; | ||
1563 | } | ||
1564 | |||
1565 | shutdown(info); | ||
1566 | dma = new_config.dma_channel; | ||
1567 | info->stat_flags &= ~ESP_STAT_NEVER_DMA; | ||
1568 | |||
1569 | /* all ports must use the same DMA channel */ | ||
1570 | |||
1571 | spin_lock_irqsave(&info->lock, flags); | ||
1572 | current_async = ports; | ||
1573 | |||
1574 | while (current_async) { | ||
1575 | esp_basic_init(current_async); | ||
1576 | current_async = current_async->next_port; | ||
1577 | } | ||
1578 | spin_unlock_irqrestore(&info->lock, flags); | ||
1579 | } else { | ||
1580 | /* DMA mode to PIO mode only */ | ||
1581 | if (info->port.count > 1) | ||
1582 | return -EBUSY; | ||
1583 | |||
1584 | shutdown(info); | ||
1585 | spin_lock_irqsave(&info->lock, flags); | ||
1586 | info->stat_flags |= ESP_STAT_NEVER_DMA; | ||
1587 | esp_basic_init(info); | ||
1588 | spin_unlock_irqrestore(&info->lock, flags); | ||
1589 | } | ||
1590 | } | ||
1591 | |||
1592 | info->config.pio_threshold = new_config.pio_threshold; | ||
1593 | |||
1594 | if ((new_config.flow_off != info->config.flow_off) || | ||
1595 | (new_config.flow_on != info->config.flow_on)) { | ||
1596 | info->config.flow_off = new_config.flow_off; | ||
1597 | info->config.flow_on = new_config.flow_on; | ||
1598 | |||
1599 | spin_lock_irqsave(&info->lock, flags); | ||
1600 | serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_LVL); | ||
1601 | serial_out(info, UART_ESI_CMD2, new_config.flow_off >> 8); | ||
1602 | serial_out(info, UART_ESI_CMD2, new_config.flow_off); | ||
1603 | serial_out(info, UART_ESI_CMD2, new_config.flow_on >> 8); | ||
1604 | serial_out(info, UART_ESI_CMD2, new_config.flow_on); | ||
1605 | spin_unlock_irqrestore(&info->lock, flags); | ||
1606 | } | ||
1607 | |||
1608 | if ((new_config.rx_trigger != info->config.rx_trigger) || | ||
1609 | (new_config.tx_trigger != info->config.tx_trigger)) { | ||
1610 | info->config.rx_trigger = new_config.rx_trigger; | ||
1611 | info->config.tx_trigger = new_config.tx_trigger; | ||
1612 | spin_lock_irqsave(&info->lock, flags); | ||
1613 | serial_out(info, UART_ESI_CMD1, ESI_SET_TRIGGER); | ||
1614 | serial_out(info, UART_ESI_CMD2, | ||
1615 | new_config.rx_trigger >> 8); | ||
1616 | serial_out(info, UART_ESI_CMD2, new_config.rx_trigger); | ||
1617 | serial_out(info, UART_ESI_CMD2, | ||
1618 | new_config.tx_trigger >> 8); | ||
1619 | serial_out(info, UART_ESI_CMD2, new_config.tx_trigger); | ||
1620 | spin_unlock_irqrestore(&info->lock, flags); | ||
1621 | } | ||
1622 | |||
1623 | if (new_config.rx_timeout != info->config.rx_timeout) { | ||
1624 | info->config.rx_timeout = new_config.rx_timeout; | ||
1625 | spin_lock_irqsave(&info->lock, flags); | ||
1626 | |||
1627 | if (info->IER & UART_IER_RDI) { | ||
1628 | serial_out(info, UART_ESI_CMD1, | ||
1629 | ESI_SET_RX_TIMEOUT); | ||
1630 | serial_out(info, UART_ESI_CMD2, | ||
1631 | new_config.rx_timeout); | ||
1632 | } | ||
1633 | |||
1634 | spin_unlock_irqrestore(&info->lock, flags); | ||
1635 | } | ||
1636 | |||
1637 | if (!(info->port.flags & ASYNC_INITIALIZED)) | ||
1638 | retval = startup(info); | ||
1639 | |||
1640 | return retval; | ||
1641 | } | ||
1642 | |||
1643 | /* | ||
1644 | * get_lsr_info - get line status register info | ||
1645 | * | ||
1646 | * Purpose: Let user call ioctl() to get info when the UART physically | ||
1647 | * is emptied. On bus types like RS485, the transmitter must | ||
1648 | * release the bus after transmitting. This must be done when | ||
1649 | * the transmit shift register is empty, not be done when the | ||
1650 | * transmit holding register is empty. This functionality | ||
1651 | * allows an RS485 driver to be written in user space. | ||
1652 | */ | ||
1653 | static int get_lsr_info(struct esp_struct *info, unsigned int __user *value) | ||
1654 | { | ||
1655 | unsigned char status; | ||
1656 | unsigned int result; | ||
1657 | unsigned long flags; | ||
1658 | |||
1659 | spin_lock_irqsave(&info->lock, flags); | ||
1660 | serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); | ||
1661 | status = serial_in(info, UART_ESI_STAT1); | ||
1662 | spin_unlock_irqrestore(&info->lock, flags); | ||
1663 | result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); | ||
1664 | return put_user(result, value); | ||
1665 | } | ||
1666 | |||
1667 | |||
1668 | static int esp_tiocmget(struct tty_struct *tty, struct file *file) | ||
1669 | { | ||
1670 | struct esp_struct *info = tty->driver_data; | ||
1671 | unsigned char control, status; | ||
1672 | unsigned long flags; | ||
1673 | |||
1674 | if (serial_paranoia_check(info, tty->name, __func__)) | ||
1675 | return -ENODEV; | ||
1676 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
1677 | return -EIO; | ||
1678 | |||
1679 | control = info->MCR; | ||
1680 | |||
1681 | spin_lock_irqsave(&info->lock, flags); | ||
1682 | serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); | ||
1683 | status = serial_in(info, UART_ESI_STAT2); | ||
1684 | spin_unlock_irqrestore(&info->lock, flags); | ||
1685 | |||
1686 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | ||
1687 | | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | ||
1688 | | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | ||
1689 | | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) | ||
1690 | | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) | ||
1691 | | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); | ||
1692 | } | ||
1693 | |||
1694 | static int esp_tiocmset(struct tty_struct *tty, struct file *file, | ||
1695 | unsigned int set, unsigned int clear) | ||
1696 | { | ||
1697 | struct esp_struct *info = tty->driver_data; | ||
1698 | unsigned long flags; | ||
1699 | |||
1700 | if (serial_paranoia_check(info, tty->name, __func__)) | ||
1701 | return -ENODEV; | ||
1702 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
1703 | return -EIO; | ||
1704 | |||
1705 | spin_lock_irqsave(&info->lock, flags); | ||
1706 | |||
1707 | if (set & TIOCM_RTS) | ||
1708 | info->MCR |= UART_MCR_RTS; | ||
1709 | if (set & TIOCM_DTR) | ||
1710 | info->MCR |= UART_MCR_DTR; | ||
1711 | |||
1712 | if (clear & TIOCM_RTS) | ||
1713 | info->MCR &= ~UART_MCR_RTS; | ||
1714 | if (clear & TIOCM_DTR) | ||
1715 | info->MCR &= ~UART_MCR_DTR; | ||
1716 | |||
1717 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | ||
1718 | serial_out(info, UART_ESI_CMD2, UART_MCR); | ||
1719 | serial_out(info, UART_ESI_CMD2, info->MCR); | ||
1720 | |||
1721 | spin_unlock_irqrestore(&info->lock, flags); | ||
1722 | return 0; | ||
1723 | } | ||
1724 | |||
1725 | /* | ||
1726 | * rs_break() --- routine which turns the break handling on or off | ||
1727 | */ | ||
1728 | static int esp_break(struct tty_struct *tty, int break_state) | ||
1729 | { | ||
1730 | struct esp_struct *info = tty->driver_data; | ||
1731 | unsigned long flags; | ||
1732 | |||
1733 | if (serial_paranoia_check(info, tty->name, "esp_break")) | ||
1734 | return -EINVAL; | ||
1735 | |||
1736 | if (break_state == -1) { | ||
1737 | spin_lock_irqsave(&info->lock, flags); | ||
1738 | serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK); | ||
1739 | serial_out(info, UART_ESI_CMD2, 0x01); | ||
1740 | spin_unlock_irqrestore(&info->lock, flags); | ||
1741 | |||
1742 | /* FIXME - new style wait needed here */ | ||
1743 | interruptible_sleep_on(&info->break_wait); | ||
1744 | } else { | ||
1745 | spin_lock_irqsave(&info->lock, flags); | ||
1746 | serial_out(info, UART_ESI_CMD1, ESI_ISSUE_BREAK); | ||
1747 | serial_out(info, UART_ESI_CMD2, 0x00); | ||
1748 | spin_unlock_irqrestore(&info->lock, flags); | ||
1749 | } | ||
1750 | return 0; | ||
1751 | } | ||
1752 | |||
1753 | static int rs_ioctl(struct tty_struct *tty, struct file *file, | ||
1754 | unsigned int cmd, unsigned long arg) | ||
1755 | { | ||
1756 | struct esp_struct *info = tty->driver_data; | ||
1757 | struct async_icount cprev, cnow; /* kernel counter temps */ | ||
1758 | struct serial_icounter_struct __user *p_cuser; /* user space */ | ||
1759 | void __user *argp = (void __user *)arg; | ||
1760 | unsigned long flags; | ||
1761 | int ret; | ||
1762 | |||
1763 | if (serial_paranoia_check(info, tty->name, "rs_ioctl")) | ||
1764 | return -ENODEV; | ||
1765 | |||
1766 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | ||
1767 | (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && | ||
1768 | (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) && | ||
1769 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT) && | ||
1770 | (cmd != TIOCGHAYESESP) && (cmd != TIOCSHAYESESP)) { | ||
1771 | if (tty->flags & (1 << TTY_IO_ERROR)) | ||
1772 | return -EIO; | ||
1773 | } | ||
1774 | |||
1775 | switch (cmd) { | ||
1776 | case TIOCGSERIAL: | ||
1777 | return get_serial_info(info, argp); | ||
1778 | case TIOCSSERIAL: | ||
1779 | lock_kernel(); | ||
1780 | ret = set_serial_info(info, argp); | ||
1781 | unlock_kernel(); | ||
1782 | return ret; | ||
1783 | case TIOCSERGWILD: | ||
1784 | return put_user(0L, (unsigned long __user *)argp); | ||
1785 | case TIOCSERGETLSR: /* Get line status register */ | ||
1786 | return get_lsr_info(info, argp); | ||
1787 | case TIOCSERSWILD: | ||
1788 | if (!capable(CAP_SYS_ADMIN)) | ||
1789 | return -EPERM; | ||
1790 | return 0; | ||
1791 | /* | ||
1792 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | ||
1793 | * - mask passed in arg for lines of interest | ||
1794 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | ||
1795 | * Caller should use TIOCGICOUNT to see which one it was | ||
1796 | */ | ||
1797 | case TIOCMIWAIT: | ||
1798 | spin_lock_irqsave(&info->lock, flags); | ||
1799 | cprev = info->icount; /* note the counters on entry */ | ||
1800 | spin_unlock_irqrestore(&info->lock, flags); | ||
1801 | while (1) { | ||
1802 | /* FIXME: convert to new style wakeup */ | ||
1803 | interruptible_sleep_on(&info->port.delta_msr_wait); | ||
1804 | /* see if a signal did it */ | ||
1805 | if (signal_pending(current)) | ||
1806 | return -ERESTARTSYS; | ||
1807 | spin_lock_irqsave(&info->lock, flags); | ||
1808 | cnow = info->icount; /* atomic copy */ | ||
1809 | spin_unlock_irqrestore(&info->lock, flags); | ||
1810 | if (cnow.rng == cprev.rng && | ||
1811 | cnow.dsr == cprev.dsr && | ||
1812 | cnow.dcd == cprev.dcd && | ||
1813 | cnow.cts == cprev.cts) | ||
1814 | return -EIO; /* no change => error */ | ||
1815 | if (((arg & TIOCM_RNG) && | ||
1816 | (cnow.rng != cprev.rng)) || | ||
1817 | ((arg & TIOCM_DSR) && | ||
1818 | (cnow.dsr != cprev.dsr)) || | ||
1819 | ((arg & TIOCM_CD) && | ||
1820 | (cnow.dcd != cprev.dcd)) || | ||
1821 | ((arg & TIOCM_CTS) && | ||
1822 | (cnow.cts != cprev.cts))) { | ||
1823 | return 0; | ||
1824 | } | ||
1825 | cprev = cnow; | ||
1826 | } | ||
1827 | /* NOTREACHED */ | ||
1828 | /* | ||
1829 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1830 | * Return: write counters to the user passed counter struct | ||
1831 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1832 | * RI where only 0->1 is counted. | ||
1833 | */ | ||
1834 | case TIOCGICOUNT: | ||
1835 | spin_lock_irqsave(&info->lock, flags); | ||
1836 | cnow = info->icount; | ||
1837 | spin_unlock_irqrestore(&info->lock, flags); | ||
1838 | p_cuser = argp; | ||
1839 | if (put_user(cnow.cts, &p_cuser->cts) || | ||
1840 | put_user(cnow.dsr, &p_cuser->dsr) || | ||
1841 | put_user(cnow.rng, &p_cuser->rng) || | ||
1842 | put_user(cnow.dcd, &p_cuser->dcd)) | ||
1843 | return -EFAULT; | ||
1844 | return 0; | ||
1845 | case TIOCGHAYESESP: | ||
1846 | return get_esp_config(info, argp); | ||
1847 | case TIOCSHAYESESP: | ||
1848 | lock_kernel(); | ||
1849 | ret = set_esp_config(info, argp); | ||
1850 | unlock_kernel(); | ||
1851 | return ret; | ||
1852 | default: | ||
1853 | return -ENOIOCTLCMD; | ||
1854 | } | ||
1855 | return 0; | ||
1856 | } | ||
1857 | |||
1858 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | ||
1859 | { | ||
1860 | struct esp_struct *info = tty->driver_data; | ||
1861 | unsigned long flags; | ||
1862 | |||
1863 | change_speed(info); | ||
1864 | |||
1865 | spin_lock_irqsave(&info->lock, flags); | ||
1866 | |||
1867 | /* Handle transition to B0 status */ | ||
1868 | if ((old_termios->c_cflag & CBAUD) && | ||
1869 | !(tty->termios->c_cflag & CBAUD)) { | ||
1870 | info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); | ||
1871 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | ||
1872 | serial_out(info, UART_ESI_CMD2, UART_MCR); | ||
1873 | serial_out(info, UART_ESI_CMD2, info->MCR); | ||
1874 | } | ||
1875 | |||
1876 | /* Handle transition away from B0 status */ | ||
1877 | if (!(old_termios->c_cflag & CBAUD) && | ||
1878 | (tty->termios->c_cflag & CBAUD)) { | ||
1879 | info->MCR |= (UART_MCR_DTR | UART_MCR_RTS); | ||
1880 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | ||
1881 | serial_out(info, UART_ESI_CMD2, UART_MCR); | ||
1882 | serial_out(info, UART_ESI_CMD2, info->MCR); | ||
1883 | } | ||
1884 | |||
1885 | spin_unlock_irqrestore(&info->lock, flags); | ||
1886 | |||
1887 | /* Handle turning of CRTSCTS */ | ||
1888 | if ((old_termios->c_cflag & CRTSCTS) && | ||
1889 | !(tty->termios->c_cflag & CRTSCTS)) { | ||
1890 | rs_start(tty); | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | /* | ||
1895 | * ------------------------------------------------------------ | ||
1896 | * rs_close() | ||
1897 | * | ||
1898 | * This routine is called when the serial port gets closed. First, we | ||
1899 | * wait for the last remaining data to be sent. Then, we unlink its | ||
1900 | * async structure from the interrupt chain if necessary, and we free | ||
1901 | * that IRQ if nothing is left in the chain. | ||
1902 | * ------------------------------------------------------------ | ||
1903 | */ | ||
1904 | static void rs_close(struct tty_struct *tty, struct file *filp) | ||
1905 | { | ||
1906 | struct esp_struct *info = tty->driver_data; | ||
1907 | unsigned long flags; | ||
1908 | |||
1909 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) | ||
1910 | return; | ||
1911 | |||
1912 | spin_lock_irqsave(&info->lock, flags); | ||
1913 | |||
1914 | if (tty_hung_up_p(filp)) { | ||
1915 | DBG_CNT("before DEC-hung"); | ||
1916 | goto out; | ||
1917 | } | ||
1918 | |||
1919 | #ifdef SERIAL_DEBUG_OPEN | ||
1920 | printk(KERN_DEBUG "rs_close ttys%d, count = %d\n", | ||
1921 | info->line, info->port.count); | ||
1922 | #endif | ||
1923 | if (tty->count == 1 && info->port.count != 1) { | ||
1924 | /* | ||
1925 | * Uh, oh. tty->count is 1, which means that the tty | ||
1926 | * structure will be freed. Info->count should always | ||
1927 | * be one in these conditions. If it's greater than | ||
1928 | * one, we've got real problems, since it means the | ||
1929 | * serial port won't be shutdown. | ||
1930 | */ | ||
1931 | printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->port.count is %d\n", info->port.count); | ||
1932 | info->port.count = 1; | ||
1933 | } | ||
1934 | if (--info->port.count < 0) { | ||
1935 | printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", | ||
1936 | info->line, info->port.count); | ||
1937 | info->port.count = 0; | ||
1938 | } | ||
1939 | if (info->port.count) { | ||
1940 | DBG_CNT("before DEC-2"); | ||
1941 | goto out; | ||
1942 | } | ||
1943 | info->port.flags |= ASYNC_CLOSING; | ||
1944 | |||
1945 | spin_unlock_irqrestore(&info->lock, flags); | ||
1946 | /* | ||
1947 | * Now we wait for the transmit buffer to clear; and we notify | ||
1948 | * the line discipline to only process XON/XOFF characters. | ||
1949 | */ | ||
1950 | tty->closing = 1; | ||
1951 | if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
1952 | tty_wait_until_sent(tty, info->closing_wait); | ||
1953 | /* | ||
1954 | * At this point we stop accepting input. To do this, we | ||
1955 | * disable the receive line status interrupts, and tell the | ||
1956 | * interrupt driver to stop checking the data ready bit in the | ||
1957 | * line status register. | ||
1958 | */ | ||
1959 | /* info->IER &= ~UART_IER_RLSI; */ | ||
1960 | info->IER &= ~UART_IER_RDI; | ||
1961 | info->read_status_mask &= ~UART_LSR_DR; | ||
1962 | if (info->port.flags & ASYNC_INITIALIZED) { | ||
1963 | |||
1964 | spin_lock_irqsave(&info->lock, flags); | ||
1965 | serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); | ||
1966 | serial_out(info, UART_ESI_CMD2, info->IER); | ||
1967 | |||
1968 | /* disable receive timeout */ | ||
1969 | serial_out(info, UART_ESI_CMD1, ESI_SET_RX_TIMEOUT); | ||
1970 | serial_out(info, UART_ESI_CMD2, 0x00); | ||
1971 | |||
1972 | spin_unlock_irqrestore(&info->lock, flags); | ||
1973 | |||
1974 | /* | ||
1975 | * Before we drop DTR, make sure the UART transmitter | ||
1976 | * has completely drained; this is especially | ||
1977 | * important if there is a transmit FIFO! | ||
1978 | */ | ||
1979 | rs_wait_until_sent(tty, info->timeout); | ||
1980 | } | ||
1981 | shutdown(info); | ||
1982 | rs_flush_buffer(tty); | ||
1983 | tty_ldisc_flush(tty); | ||
1984 | tty->closing = 0; | ||
1985 | info->port.tty = NULL; | ||
1986 | |||
1987 | if (info->port.blocked_open) { | ||
1988 | if (info->close_delay) | ||
1989 | msleep_interruptible(jiffies_to_msecs(info->close_delay)); | ||
1990 | wake_up_interruptible(&info->port.open_wait); | ||
1991 | } | ||
1992 | info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | ||
1993 | wake_up_interruptible(&info->port.close_wait); | ||
1994 | return; | ||
1995 | |||
1996 | out: | ||
1997 | spin_unlock_irqrestore(&info->lock, flags); | ||
1998 | } | ||
1999 | |||
2000 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | ||
2001 | { | ||
2002 | struct esp_struct *info = tty->driver_data; | ||
2003 | unsigned long orig_jiffies, char_time; | ||
2004 | unsigned long flags; | ||
2005 | |||
2006 | if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) | ||
2007 | return; | ||
2008 | |||
2009 | orig_jiffies = jiffies; | ||
2010 | char_time = ((info->timeout - HZ / 50) / 1024) / 5; | ||
2011 | |||
2012 | if (!char_time) | ||
2013 | char_time = 1; | ||
2014 | |||
2015 | spin_lock_irqsave(&info->lock, flags); | ||
2016 | serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); | ||
2017 | serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL); | ||
2018 | |||
2019 | while ((serial_in(info, UART_ESI_STAT1) != 0x03) || | ||
2020 | (serial_in(info, UART_ESI_STAT2) != 0xff)) { | ||
2021 | |||
2022 | spin_unlock_irqrestore(&info->lock, flags); | ||
2023 | msleep_interruptible(jiffies_to_msecs(char_time)); | ||
2024 | |||
2025 | if (signal_pending(current)) | ||
2026 | return; | ||
2027 | |||
2028 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | ||
2029 | return; | ||
2030 | |||
2031 | spin_lock_irqsave(&info->lock, flags); | ||
2032 | serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND); | ||
2033 | serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL); | ||
2034 | } | ||
2035 | spin_unlock_irqrestore(&info->lock, flags); | ||
2036 | set_current_state(TASK_RUNNING); | ||
2037 | } | ||
2038 | |||
2039 | /* | ||
2040 | * esp_hangup() --- called by tty_hangup() when a hangup is signaled. | ||
2041 | */ | ||
2042 | static void esp_hangup(struct tty_struct *tty) | ||
2043 | { | ||
2044 | struct esp_struct *info = tty->driver_data; | ||
2045 | |||
2046 | if (serial_paranoia_check(info, tty->name, "esp_hangup")) | ||
2047 | return; | ||
2048 | |||
2049 | rs_flush_buffer(tty); | ||
2050 | shutdown(info); | ||
2051 | info->port.count = 0; | ||
2052 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | ||
2053 | info->port.tty = NULL; | ||
2054 | wake_up_interruptible(&info->port.open_wait); | ||
2055 | } | ||
2056 | |||
2057 | static int esp_carrier_raised(struct tty_port *port) | ||
2058 | { | ||
2059 | struct esp_struct *info = container_of(port, struct esp_struct, port); | ||
2060 | serial_out(info, UART_ESI_CMD1, ESI_GET_UART_STAT); | ||
2061 | if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD) | ||
2062 | return 1; | ||
2063 | return 0; | ||
2064 | } | ||
2065 | |||
2066 | /* | ||
2067 | * ------------------------------------------------------------ | ||
2068 | * esp_open() and friends | ||
2069 | * ------------------------------------------------------------ | ||
2070 | */ | ||
2071 | static int block_til_ready(struct tty_struct *tty, struct file *filp, | ||
2072 | struct esp_struct *info) | ||
2073 | { | ||
2074 | DECLARE_WAITQUEUE(wait, current); | ||
2075 | int retval; | ||
2076 | int do_clocal = 0; | ||
2077 | unsigned long flags; | ||
2078 | int cd; | ||
2079 | struct tty_port *port = &info->port; | ||
2080 | |||
2081 | /* | ||
2082 | * If the device is in the middle of being closed, then block | ||
2083 | * until it's done, and then try again. | ||
2084 | */ | ||
2085 | if (tty_hung_up_p(filp) || | ||
2086 | (port->flags & ASYNC_CLOSING)) { | ||
2087 | if (port->flags & ASYNC_CLOSING) | ||
2088 | interruptible_sleep_on(&port->close_wait); | ||
2089 | #ifdef SERIAL_DO_RESTART | ||
2090 | if (port->flags & ASYNC_HUP_NOTIFY) | ||
2091 | return -EAGAIN; | ||
2092 | else | ||
2093 | return -ERESTARTSYS; | ||
2094 | #else | ||
2095 | return -EAGAIN; | ||
2096 | #endif | ||
2097 | } | ||
2098 | |||
2099 | /* | ||
2100 | * If non-blocking mode is set, or the port is not enabled, | ||
2101 | * then make the check up front and then exit. | ||
2102 | */ | ||
2103 | if ((filp->f_flags & O_NONBLOCK) || | ||
2104 | (tty->flags & (1 << TTY_IO_ERROR))) { | ||
2105 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
2106 | return 0; | ||
2107 | } | ||
2108 | |||
2109 | if (tty->termios->c_cflag & CLOCAL) | ||
2110 | do_clocal = 1; | ||
2111 | |||
2112 | /* | ||
2113 | * Block waiting for the carrier detect and the line to become | ||
2114 | * free (i.e., not in use by the callout). While we are in | ||
2115 | * this loop, port->count is dropped by one, so that | ||
2116 | * rs_close() knows when to free things. We restore it upon | ||
2117 | * exit, either normal or abnormal. | ||
2118 | */ | ||
2119 | retval = 0; | ||
2120 | add_wait_queue(&port->open_wait, &wait); | ||
2121 | #ifdef SERIAL_DEBUG_OPEN | ||
2122 | printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n", | ||
2123 | info->line, port->count); | ||
2124 | #endif | ||
2125 | spin_lock_irqsave(&info->lock, flags); | ||
2126 | if (!tty_hung_up_p(filp)) | ||
2127 | port->count--; | ||
2128 | port->blocked_open++; | ||
2129 | while (1) { | ||
2130 | if ((tty->termios->c_cflag & CBAUD)) { | ||
2131 | unsigned int scratch; | ||
2132 | |||
2133 | serial_out(info, UART_ESI_CMD1, ESI_READ_UART); | ||
2134 | serial_out(info, UART_ESI_CMD2, UART_MCR); | ||
2135 | scratch = serial_in(info, UART_ESI_STAT1); | ||
2136 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | ||
2137 | serial_out(info, UART_ESI_CMD2, UART_MCR); | ||
2138 | serial_out(info, UART_ESI_CMD2, | ||
2139 | scratch | UART_MCR_DTR | UART_MCR_RTS); | ||
2140 | } | ||
2141 | set_current_state(TASK_INTERRUPTIBLE); | ||
2142 | if (tty_hung_up_p(filp) || | ||
2143 | !(port->flags & ASYNC_INITIALIZED)) { | ||
2144 | #ifdef SERIAL_DO_RESTART | ||
2145 | if (port->flags & ASYNC_HUP_NOTIFY) | ||
2146 | retval = -EAGAIN; | ||
2147 | else | ||
2148 | retval = -ERESTARTSYS; | ||
2149 | #else | ||
2150 | retval = -EAGAIN; | ||
2151 | #endif | ||
2152 | break; | ||
2153 | } | ||
2154 | |||
2155 | cd = tty_port_carrier_raised(port); | ||
2156 | |||
2157 | if (!(port->flags & ASYNC_CLOSING) && | ||
2158 | (do_clocal)) | ||
2159 | break; | ||
2160 | if (signal_pending(current)) { | ||
2161 | retval = -ERESTARTSYS; | ||
2162 | break; | ||
2163 | } | ||
2164 | #ifdef SERIAL_DEBUG_OPEN | ||
2165 | printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n", | ||
2166 | info->line, port->count); | ||
2167 | #endif | ||
2168 | spin_unlock_irqrestore(&info->lock, flags); | ||
2169 | schedule(); | ||
2170 | spin_lock_irqsave(&info->lock, flags); | ||
2171 | } | ||
2172 | set_current_state(TASK_RUNNING); | ||
2173 | remove_wait_queue(&port->open_wait, &wait); | ||
2174 | if (!tty_hung_up_p(filp)) | ||
2175 | port->count++; | ||
2176 | port->blocked_open--; | ||
2177 | spin_unlock_irqrestore(&info->lock, flags); | ||
2178 | #ifdef SERIAL_DEBUG_OPEN | ||
2179 | printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n", | ||
2180 | info->line, port->count); | ||
2181 | #endif | ||
2182 | if (retval) | ||
2183 | return retval; | ||
2184 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
2185 | return 0; | ||
2186 | } | ||
2187 | |||
2188 | /* | ||
2189 | * This routine is called whenever a serial port is opened. It | ||
2190 | * enables interrupts for a serial port, linking in its async structure into | ||
2191 | * the IRQ chain. It also performs the serial-specific | ||
2192 | * initialization for the tty structure. | ||
2193 | */ | ||
2194 | static int esp_open(struct tty_struct *tty, struct file *filp) | ||
2195 | { | ||
2196 | struct esp_struct *info; | ||
2197 | int retval, line; | ||
2198 | unsigned long flags; | ||
2199 | |||
2200 | line = tty->index; | ||
2201 | if ((line < 0) || (line >= NR_PORTS)) | ||
2202 | return -ENODEV; | ||
2203 | |||
2204 | /* find the port in the chain */ | ||
2205 | |||
2206 | info = ports; | ||
2207 | |||
2208 | while (info && (info->line != line)) | ||
2209 | info = info->next_port; | ||
2210 | |||
2211 | if (!info) { | ||
2212 | serial_paranoia_check(info, tty->name, "esp_open"); | ||
2213 | return -ENODEV; | ||
2214 | } | ||
2215 | |||
2216 | #ifdef SERIAL_DEBUG_OPEN | ||
2217 | printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->port.count); | ||
2218 | #endif | ||
2219 | spin_lock_irqsave(&info->lock, flags); | ||
2220 | info->port.count++; | ||
2221 | tty->driver_data = info; | ||
2222 | info->port.tty = tty; | ||
2223 | |||
2224 | spin_unlock_irqrestore(&info->lock, flags); | ||
2225 | |||
2226 | /* | ||
2227 | * Start up serial port | ||
2228 | */ | ||
2229 | retval = startup(info); | ||
2230 | if (retval) | ||
2231 | return retval; | ||
2232 | |||
2233 | retval = block_til_ready(tty, filp, info); | ||
2234 | if (retval) { | ||
2235 | #ifdef SERIAL_DEBUG_OPEN | ||
2236 | printk(KERN_DEBUG "esp_open returning after block_til_ready with %d\n", | ||
2237 | retval); | ||
2238 | #endif | ||
2239 | return retval; | ||
2240 | } | ||
2241 | #ifdef SERIAL_DEBUG_OPEN | ||
2242 | printk(KERN_DEBUG "esp_open %s successful...", tty->name); | ||
2243 | #endif | ||
2244 | return 0; | ||
2245 | } | ||
2246 | |||
2247 | /* | ||
2248 | * --------------------------------------------------------------------- | ||
2249 | * espserial_init() and friends | ||
2250 | * | ||
2251 | * espserial_init() is called at boot-time to initialize the serial driver. | ||
2252 | * --------------------------------------------------------------------- | ||
2253 | */ | ||
2254 | |||
2255 | /* | ||
2256 | * This routine prints out the appropriate serial driver version | ||
2257 | * number, and identifies which options were configured into this | ||
2258 | * driver. | ||
2259 | */ | ||
2260 | |||
2261 | static void __init show_serial_version(void) | ||
2262 | { | ||
2263 | printk(KERN_INFO "%s version %s (DMA %u)\n", | ||
2264 | serial_name, serial_version, dma); | ||
2265 | } | ||
2266 | |||
2267 | /* | ||
2268 | * This routine is called by espserial_init() to initialize a specific serial | ||
2269 | * port. | ||
2270 | */ | ||
2271 | static int autoconfig(struct esp_struct *info) | ||
2272 | { | ||
2273 | int port_detected = 0; | ||
2274 | unsigned long flags; | ||
2275 | |||
2276 | if (!request_region(info->io_port, REGION_SIZE, "esp serial")) | ||
2277 | return -EIO; | ||
2278 | |||
2279 | spin_lock_irqsave(&info->lock, flags); | ||
2280 | /* | ||
2281 | * Check for ESP card | ||
2282 | */ | ||
2283 | |||
2284 | if (serial_in(info, UART_ESI_BASE) == 0xf3) { | ||
2285 | serial_out(info, UART_ESI_CMD1, 0x00); | ||
2286 | serial_out(info, UART_ESI_CMD1, 0x01); | ||
2287 | |||
2288 | if ((serial_in(info, UART_ESI_STAT2) & 0x70) == 0x20) { | ||
2289 | port_detected = 1; | ||
2290 | |||
2291 | if (!(info->irq)) { | ||
2292 | serial_out(info, UART_ESI_CMD1, 0x02); | ||
2293 | |||
2294 | if (serial_in(info, UART_ESI_STAT1) & 0x01) | ||
2295 | info->irq = 3; | ||
2296 | else | ||
2297 | info->irq = 4; | ||
2298 | } | ||
2299 | |||
2300 | |||
2301 | /* put card in enhanced mode */ | ||
2302 | /* this prevents access through */ | ||
2303 | /* the "old" IO ports */ | ||
2304 | esp_basic_init(info); | ||
2305 | |||
2306 | /* clear out MCR */ | ||
2307 | serial_out(info, UART_ESI_CMD1, ESI_WRITE_UART); | ||
2308 | serial_out(info, UART_ESI_CMD2, UART_MCR); | ||
2309 | serial_out(info, UART_ESI_CMD2, 0x00); | ||
2310 | } | ||
2311 | } | ||
2312 | if (!port_detected) | ||
2313 | release_region(info->io_port, REGION_SIZE); | ||
2314 | |||
2315 | spin_unlock_irqrestore(&info->lock, flags); | ||
2316 | return (port_detected); | ||
2317 | } | ||
2318 | |||
2319 | static const struct tty_operations esp_ops = { | ||
2320 | .open = esp_open, | ||
2321 | .close = rs_close, | ||
2322 | .write = rs_write, | ||
2323 | .put_char = rs_put_char, | ||
2324 | .flush_chars = rs_flush_chars, | ||
2325 | .write_room = rs_write_room, | ||
2326 | .chars_in_buffer = rs_chars_in_buffer, | ||
2327 | .flush_buffer = rs_flush_buffer, | ||
2328 | .ioctl = rs_ioctl, | ||
2329 | .throttle = rs_throttle, | ||
2330 | .unthrottle = rs_unthrottle, | ||
2331 | .set_termios = rs_set_termios, | ||
2332 | .stop = rs_stop, | ||
2333 | .start = rs_start, | ||
2334 | .hangup = esp_hangup, | ||
2335 | .break_ctl = esp_break, | ||
2336 | .wait_until_sent = rs_wait_until_sent, | ||
2337 | .tiocmget = esp_tiocmget, | ||
2338 | .tiocmset = esp_tiocmset, | ||
2339 | }; | ||
2340 | |||
2341 | static const struct tty_port_operations esp_port_ops = { | ||
2342 | .esp_carrier_raised, | ||
2343 | }; | ||
2344 | |||
2345 | /* | ||
2346 | * The serial driver boot-time initialization code! | ||
2347 | */ | ||
2348 | static int __init espserial_init(void) | ||
2349 | { | ||
2350 | int i, offset; | ||
2351 | struct esp_struct *info; | ||
2352 | struct esp_struct *last_primary = NULL; | ||
2353 | int esp[] = { 0x100, 0x140, 0x180, 0x200, 0x240, 0x280, 0x300, 0x380 }; | ||
2354 | |||
2355 | esp_driver = alloc_tty_driver(NR_PORTS); | ||
2356 | if (!esp_driver) | ||
2357 | return -ENOMEM; | ||
2358 | |||
2359 | for (i = 0; i < NR_PRIMARY; i++) { | ||
2360 | if (irq[i] != 0) { | ||
2361 | if ((irq[i] < 2) || (irq[i] > 15) || (irq[i] == 6) || | ||
2362 | (irq[i] == 8) || (irq[i] == 13)) | ||
2363 | irq[i] = 0; | ||
2364 | else if (irq[i] == 2) | ||
2365 | irq[i] = 9; | ||
2366 | } | ||
2367 | } | ||
2368 | |||
2369 | if ((dma != 1) && (dma != 3)) | ||
2370 | dma = 0; | ||
2371 | |||
2372 | if ((rx_trigger < 1) || (rx_trigger > 1023)) | ||
2373 | rx_trigger = 768; | ||
2374 | |||
2375 | if ((tx_trigger < 1) || (tx_trigger > 1023)) | ||
2376 | tx_trigger = 768; | ||
2377 | |||
2378 | if ((flow_off < 1) || (flow_off > 1023)) | ||
2379 | flow_off = 1016; | ||
2380 | |||
2381 | if ((flow_on < 1) || (flow_on > 1023)) | ||
2382 | flow_on = 944; | ||
2383 | |||
2384 | if ((rx_timeout < 0) || (rx_timeout > 255)) | ||
2385 | rx_timeout = 128; | ||
2386 | |||
2387 | if (flow_on >= flow_off) | ||
2388 | flow_on = flow_off - 1; | ||
2389 | |||
2390 | show_serial_version(); | ||
2391 | |||
2392 | /* Initialize the tty_driver structure */ | ||
2393 | |||
2394 | esp_driver->owner = THIS_MODULE; | ||
2395 | esp_driver->name = "ttyP"; | ||
2396 | esp_driver->major = ESP_IN_MAJOR; | ||
2397 | esp_driver->minor_start = 0; | ||
2398 | esp_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
2399 | esp_driver->subtype = SERIAL_TYPE_NORMAL; | ||
2400 | esp_driver->init_termios = tty_std_termios; | ||
2401 | esp_driver->init_termios.c_cflag = | ||
2402 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | ||
2403 | esp_driver->init_termios.c_ispeed = 9600; | ||
2404 | esp_driver->init_termios.c_ospeed = 9600; | ||
2405 | esp_driver->flags = TTY_DRIVER_REAL_RAW; | ||
2406 | tty_set_operations(esp_driver, &esp_ops); | ||
2407 | if (tty_register_driver(esp_driver)) { | ||
2408 | printk(KERN_ERR "Couldn't register esp serial driver"); | ||
2409 | put_tty_driver(esp_driver); | ||
2410 | return 1; | ||
2411 | } | ||
2412 | |||
2413 | info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL); | ||
2414 | |||
2415 | if (!info) { | ||
2416 | printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); | ||
2417 | tty_unregister_driver(esp_driver); | ||
2418 | put_tty_driver(esp_driver); | ||
2419 | return 1; | ||
2420 | } | ||
2421 | |||
2422 | spin_lock_init(&info->lock); | ||
2423 | /* rx_trigger, tx_trigger are needed by autoconfig */ | ||
2424 | info->config.rx_trigger = rx_trigger; | ||
2425 | info->config.tx_trigger = tx_trigger; | ||
2426 | |||
2427 | i = 0; | ||
2428 | offset = 0; | ||
2429 | |||
2430 | do { | ||
2431 | tty_port_init(&info->port); | ||
2432 | info->port.ops = &esp_port_ops; | ||
2433 | info->io_port = esp[i] + offset; | ||
2434 | info->irq = irq[i]; | ||
2435 | info->line = (i * 8) + (offset / 8); | ||
2436 | |||
2437 | if (!autoconfig(info)) { | ||
2438 | i++; | ||
2439 | offset = 0; | ||
2440 | continue; | ||
2441 | } | ||
2442 | |||
2443 | info->custom_divisor = (divisor[i] >> (offset / 2)) & 0xf; | ||
2444 | info->port.flags = STD_COM_FLAGS; | ||
2445 | if (info->custom_divisor) | ||
2446 | info->port.flags |= ASYNC_SPD_CUST; | ||
2447 | info->magic = ESP_MAGIC; | ||
2448 | info->close_delay = 5*HZ/10; | ||
2449 | info->closing_wait = 30*HZ; | ||
2450 | info->config.rx_timeout = rx_timeout; | ||
2451 | info->config.flow_on = flow_on; | ||
2452 | info->config.flow_off = flow_off; | ||
2453 | info->config.pio_threshold = pio_threshold; | ||
2454 | info->next_port = ports; | ||
2455 | init_waitqueue_head(&info->break_wait); | ||
2456 | ports = info; | ||
2457 | printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ", | ||
2458 | info->line, info->io_port, info->irq); | ||
2459 | |||
2460 | if (info->line % 8) { | ||
2461 | printk("secondary port\n"); | ||
2462 | /* 8 port cards can't do DMA */ | ||
2463 | info->stat_flags |= ESP_STAT_NEVER_DMA; | ||
2464 | |||
2465 | if (last_primary) | ||
2466 | last_primary->stat_flags |= ESP_STAT_NEVER_DMA; | ||
2467 | } else { | ||
2468 | printk("primary port\n"); | ||
2469 | last_primary = info; | ||
2470 | irq[i] = info->irq; | ||
2471 | } | ||
2472 | |||
2473 | if (!dma) | ||
2474 | info->stat_flags |= ESP_STAT_NEVER_DMA; | ||
2475 | |||
2476 | info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL); | ||
2477 | if (!info) { | ||
2478 | printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n"); | ||
2479 | /* allow use of the already detected ports */ | ||
2480 | return 0; | ||
2481 | } | ||
2482 | |||
2483 | spin_lock_init(&info->lock); | ||
2484 | /* rx_trigger, tx_trigger are needed by autoconfig */ | ||
2485 | info->config.rx_trigger = rx_trigger; | ||
2486 | info->config.tx_trigger = tx_trigger; | ||
2487 | |||
2488 | if (offset == 56) { | ||
2489 | i++; | ||
2490 | offset = 0; | ||
2491 | } else { | ||
2492 | offset += 8; | ||
2493 | } | ||
2494 | } while (i < NR_PRIMARY); | ||
2495 | |||
2496 | /* free the last port memory allocation */ | ||
2497 | kfree(info); | ||
2498 | |||
2499 | return 0; | ||
2500 | } | ||
2501 | |||
2502 | static void __exit espserial_exit(void) | ||
2503 | { | ||
2504 | int e1; | ||
2505 | struct esp_struct *temp_async; | ||
2506 | struct esp_pio_buffer *pio_buf; | ||
2507 | |||
2508 | e1 = tty_unregister_driver(esp_driver); | ||
2509 | if (e1) | ||
2510 | printk(KERN_ERR "esp: failed to unregister driver (%d)\n", e1); | ||
2511 | put_tty_driver(esp_driver); | ||
2512 | |||
2513 | while (ports) { | ||
2514 | if (ports->io_port) | ||
2515 | release_region(ports->io_port, REGION_SIZE); | ||
2516 | temp_async = ports->next_port; | ||
2517 | kfree(ports); | ||
2518 | ports = temp_async; | ||
2519 | } | ||
2520 | |||
2521 | if (dma_buffer) | ||
2522 | free_pages((unsigned long)dma_buffer, | ||
2523 | get_order(DMA_BUFFER_SZ)); | ||
2524 | |||
2525 | while (free_pio_buf) { | ||
2526 | pio_buf = free_pio_buf->next; | ||
2527 | kfree(free_pio_buf); | ||
2528 | free_pio_buf = pio_buf; | ||
2529 | } | ||
2530 | } | ||
2531 | |||
2532 | module_init(espserial_init); | ||
2533 | module_exit(espserial_exit); | ||
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index ef31738c2cbe..fda4181b5e67 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/miscdevice.h> | 19 | #include <linux/miscdevice.h> |
20 | #include <linux/fcntl.h> | 20 | #include <linux/fcntl.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
24 | #include <asm/nvram.h> | 23 | #include <asm/nvram.h> |
25 | #ifdef CONFIG_PPC_PMAC | 24 | #ifdef CONFIG_PPC_PMAC |
@@ -32,7 +31,6 @@ static ssize_t nvram_len; | |||
32 | 31 | ||
33 | static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) | 32 | static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) |
34 | { | 33 | { |
35 | lock_kernel(); | ||
36 | switch (origin) { | 34 | switch (origin) { |
37 | case 1: | 35 | case 1: |
38 | offset += file->f_pos; | 36 | offset += file->f_pos; |
@@ -41,12 +39,11 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) | |||
41 | offset += nvram_len; | 39 | offset += nvram_len; |
42 | break; | 40 | break; |
43 | } | 41 | } |
44 | if (offset < 0) { | 42 | if (offset < 0) |
45 | unlock_kernel(); | ||
46 | return -EINVAL; | 43 | return -EINVAL; |
47 | } | 44 | |
48 | file->f_pos = offset; | 45 | file->f_pos = offset; |
49 | unlock_kernel(); | 46 | |
50 | return file->f_pos; | 47 | return file->f_pos; |
51 | } | 48 | } |
52 | 49 | ||
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 70a770ac0138..e481c5938bad 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -675,36 +675,33 @@ static int hpet_is_known(struct hpet_data *hdp) | |||
675 | 675 | ||
676 | static ctl_table hpet_table[] = { | 676 | static ctl_table hpet_table[] = { |
677 | { | 677 | { |
678 | .ctl_name = CTL_UNNUMBERED, | ||
679 | .procname = "max-user-freq", | 678 | .procname = "max-user-freq", |
680 | .data = &hpet_max_freq, | 679 | .data = &hpet_max_freq, |
681 | .maxlen = sizeof(int), | 680 | .maxlen = sizeof(int), |
682 | .mode = 0644, | 681 | .mode = 0644, |
683 | .proc_handler = &proc_dointvec, | 682 | .proc_handler = proc_dointvec, |
684 | }, | 683 | }, |
685 | {.ctl_name = 0} | 684 | {} |
686 | }; | 685 | }; |
687 | 686 | ||
688 | static ctl_table hpet_root[] = { | 687 | static ctl_table hpet_root[] = { |
689 | { | 688 | { |
690 | .ctl_name = CTL_UNNUMBERED, | ||
691 | .procname = "hpet", | 689 | .procname = "hpet", |
692 | .maxlen = 0, | 690 | .maxlen = 0, |
693 | .mode = 0555, | 691 | .mode = 0555, |
694 | .child = hpet_table, | 692 | .child = hpet_table, |
695 | }, | 693 | }, |
696 | {.ctl_name = 0} | 694 | {} |
697 | }; | 695 | }; |
698 | 696 | ||
699 | static ctl_table dev_root[] = { | 697 | static ctl_table dev_root[] = { |
700 | { | 698 | { |
701 | .ctl_name = CTL_DEV, | ||
702 | .procname = "dev", | 699 | .procname = "dev", |
703 | .maxlen = 0, | 700 | .maxlen = 0, |
704 | .mode = 0555, | 701 | .mode = 0555, |
705 | .child = hpet_root, | 702 | .child = hpet_root, |
706 | }, | 703 | }, |
707 | {.ctl_name = 0} | 704 | {} |
708 | }; | 705 | }; |
709 | 706 | ||
710 | static struct ctl_table_header *sysctl_header; | 707 | static struct ctl_table_header *sysctl_header; |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index a632f25f144a..416d3423150d 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -832,6 +832,7 @@ int hvc_remove(struct hvc_struct *hp) | |||
832 | tty_hangup(tty); | 832 | tty_hangup(tty); |
833 | return 0; | 833 | return 0; |
834 | } | 834 | } |
835 | EXPORT_SYMBOL_GPL(hvc_remove); | ||
835 | 836 | ||
836 | /* Driver initialization: called as soon as someone uses hvc_alloc(). */ | 837 | /* Driver initialization: called as soon as someone uses hvc_alloc(). */ |
837 | static int hvc_init(void) | 838 | static int hvc_init(void) |
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c index b8a5d654d3d0..fe62bd0e17b7 100644 --- a/drivers/char/hvc_iucv.c +++ b/drivers/char/hvc_iucv.c | |||
@@ -931,7 +931,7 @@ static struct hv_ops hvc_iucv_ops = { | |||
931 | }; | 931 | }; |
932 | 932 | ||
933 | /* Suspend / resume device operations */ | 933 | /* Suspend / resume device operations */ |
934 | static struct dev_pm_ops hvc_iucv_pm_ops = { | 934 | static const struct dev_pm_ops hvc_iucv_pm_ops = { |
935 | .freeze = hvc_iucv_pm_freeze, | 935 | .freeze = hvc_iucv_pm_freeze, |
936 | .thaw = hvc_iucv_pm_restore_thaw, | 936 | .thaw = hvc_iucv_pm_restore_thaw, |
937 | .restore = hvc_iucv_pm_restore_thaw, | 937 | .restore = hvc_iucv_pm_restore_thaw, |
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index a6ee32b599a8..b1a71638c772 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | 26 | ||
27 | #include <asm/xen/hypervisor.h> | 27 | #include <asm/xen/hypervisor.h> |
28 | |||
29 | #include <xen/xen.h> | ||
28 | #include <xen/page.h> | 30 | #include <xen/page.h> |
29 | #include <xen/events.h> | 31 | #include <xen/events.h> |
30 | #include <xen/interface/io/console.h> | 32 | #include <xen/interface/io/console.h> |
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 1573aebd54b5..3d9c61e5acbf 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c | |||
@@ -52,7 +52,9 @@ | |||
52 | static struct hwrng *current_rng; | 52 | static struct hwrng *current_rng; |
53 | static LIST_HEAD(rng_list); | 53 | static LIST_HEAD(rng_list); |
54 | static DEFINE_MUTEX(rng_mutex); | 54 | static DEFINE_MUTEX(rng_mutex); |
55 | 55 | static int data_avail; | |
56 | static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES] | ||
57 | __cacheline_aligned; | ||
56 | 58 | ||
57 | static inline int hwrng_init(struct hwrng *rng) | 59 | static inline int hwrng_init(struct hwrng *rng) |
58 | { | 60 | { |
@@ -67,19 +69,6 @@ static inline void hwrng_cleanup(struct hwrng *rng) | |||
67 | rng->cleanup(rng); | 69 | rng->cleanup(rng); |
68 | } | 70 | } |
69 | 71 | ||
70 | static inline int hwrng_data_present(struct hwrng *rng, int wait) | ||
71 | { | ||
72 | if (!rng->data_present) | ||
73 | return 1; | ||
74 | return rng->data_present(rng, wait); | ||
75 | } | ||
76 | |||
77 | static inline int hwrng_data_read(struct hwrng *rng, u32 *data) | ||
78 | { | ||
79 | return rng->data_read(rng, data); | ||
80 | } | ||
81 | |||
82 | |||
83 | static int rng_dev_open(struct inode *inode, struct file *filp) | 72 | static int rng_dev_open(struct inode *inode, struct file *filp) |
84 | { | 73 | { |
85 | /* enforce read-only access to this chrdev */ | 74 | /* enforce read-only access to this chrdev */ |
@@ -87,60 +76,93 @@ static int rng_dev_open(struct inode *inode, struct file *filp) | |||
87 | return -EINVAL; | 76 | return -EINVAL; |
88 | if (filp->f_mode & FMODE_WRITE) | 77 | if (filp->f_mode & FMODE_WRITE) |
89 | return -EINVAL; | 78 | return -EINVAL; |
90 | cycle_kernel_lock(); | 79 | return 0; |
80 | } | ||
81 | |||
82 | static inline int rng_get_data(struct hwrng *rng, u8 *buffer, size_t size, | ||
83 | int wait) { | ||
84 | int present; | ||
85 | |||
86 | if (rng->read) | ||
87 | return rng->read(rng, (void *)buffer, size, wait); | ||
88 | |||
89 | if (rng->data_present) | ||
90 | present = rng->data_present(rng, wait); | ||
91 | else | ||
92 | present = 1; | ||
93 | |||
94 | if (present) | ||
95 | return rng->data_read(rng, (u32 *)buffer); | ||
96 | |||
91 | return 0; | 97 | return 0; |
92 | } | 98 | } |
93 | 99 | ||
94 | static ssize_t rng_dev_read(struct file *filp, char __user *buf, | 100 | static ssize_t rng_dev_read(struct file *filp, char __user *buf, |
95 | size_t size, loff_t *offp) | 101 | size_t size, loff_t *offp) |
96 | { | 102 | { |
97 | u32 data; | ||
98 | ssize_t ret = 0; | 103 | ssize_t ret = 0; |
99 | int err = 0; | 104 | int err = 0; |
100 | int bytes_read; | 105 | int bytes_read, len; |
101 | 106 | ||
102 | while (size) { | 107 | while (size) { |
103 | err = -ERESTARTSYS; | 108 | if (mutex_lock_interruptible(&rng_mutex)) { |
104 | if (mutex_lock_interruptible(&rng_mutex)) | 109 | err = -ERESTARTSYS; |
105 | goto out; | 110 | goto out; |
111 | } | ||
112 | |||
106 | if (!current_rng) { | 113 | if (!current_rng) { |
107 | mutex_unlock(&rng_mutex); | ||
108 | err = -ENODEV; | 114 | err = -ENODEV; |
109 | goto out; | 115 | goto out_unlock; |
110 | } | 116 | } |
111 | 117 | ||
112 | bytes_read = 0; | 118 | if (!data_avail) { |
113 | if (hwrng_data_present(current_rng, | 119 | bytes_read = rng_get_data(current_rng, rng_buffer, |
114 | !(filp->f_flags & O_NONBLOCK))) | 120 | sizeof(rng_buffer), |
115 | bytes_read = hwrng_data_read(current_rng, &data); | 121 | !(filp->f_flags & O_NONBLOCK)); |
116 | mutex_unlock(&rng_mutex); | 122 | if (bytes_read < 0) { |
117 | 123 | err = bytes_read; | |
118 | err = -EAGAIN; | 124 | goto out_unlock; |
119 | if (!bytes_read && (filp->f_flags & O_NONBLOCK)) | 125 | } |
120 | goto out; | 126 | data_avail = bytes_read; |
121 | if (bytes_read < 0) { | ||
122 | err = bytes_read; | ||
123 | goto out; | ||
124 | } | 127 | } |
125 | 128 | ||
126 | err = -EFAULT; | 129 | if (!data_avail) { |
127 | while (bytes_read && size) { | 130 | if (filp->f_flags & O_NONBLOCK) { |
128 | if (put_user((u8)data, buf++)) | 131 | err = -EAGAIN; |
129 | goto out; | 132 | goto out_unlock; |
130 | size--; | 133 | } |
131 | ret++; | 134 | } else { |
132 | bytes_read--; | 135 | len = data_avail; |
133 | data >>= 8; | 136 | if (len > size) |
137 | len = size; | ||
138 | |||
139 | data_avail -= len; | ||
140 | |||
141 | if (copy_to_user(buf + ret, rng_buffer + data_avail, | ||
142 | len)) { | ||
143 | err = -EFAULT; | ||
144 | goto out_unlock; | ||
145 | } | ||
146 | |||
147 | size -= len; | ||
148 | ret += len; | ||
134 | } | 149 | } |
135 | 150 | ||
151 | mutex_unlock(&rng_mutex); | ||
152 | |||
136 | if (need_resched()) | 153 | if (need_resched()) |
137 | schedule_timeout_interruptible(1); | 154 | schedule_timeout_interruptible(1); |
138 | err = -ERESTARTSYS; | 155 | |
139 | if (signal_pending(current)) | 156 | if (signal_pending(current)) { |
157 | err = -ERESTARTSYS; | ||
140 | goto out; | 158 | goto out; |
159 | } | ||
141 | } | 160 | } |
142 | out: | 161 | out: |
143 | return ret ? : err; | 162 | return ret ? : err; |
163 | out_unlock: | ||
164 | mutex_unlock(&rng_mutex); | ||
165 | goto out; | ||
144 | } | 166 | } |
145 | 167 | ||
146 | 168 | ||
@@ -280,7 +302,7 @@ int hwrng_register(struct hwrng *rng) | |||
280 | struct hwrng *old_rng, *tmp; | 302 | struct hwrng *old_rng, *tmp; |
281 | 303 | ||
282 | if (rng->name == NULL || | 304 | if (rng->name == NULL || |
283 | rng->data_read == NULL) | 305 | (rng->data_read == NULL && rng->read == NULL)) |
284 | goto out; | 306 | goto out; |
285 | 307 | ||
286 | mutex_lock(&rng_mutex); | 308 | mutex_lock(&rng_mutex); |
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 915157fcff98..bdaef8e94021 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 | */ | 18 | */ |
19 | |||
19 | #include <linux/err.h> | 20 | #include <linux/err.h> |
20 | #include <linux/hw_random.h> | 21 | #include <linux/hw_random.h> |
21 | #include <linux/scatterlist.h> | 22 | #include <linux/scatterlist.h> |
@@ -23,78 +24,64 @@ | |||
23 | #include <linux/virtio.h> | 24 | #include <linux/virtio.h> |
24 | #include <linux/virtio_rng.h> | 25 | #include <linux/virtio_rng.h> |
25 | 26 | ||
26 | /* The host will fill any buffer we give it with sweet, sweet randomness. We | ||
27 | * give it 64 bytes at a time, and the hwrng framework takes it 4 bytes at a | ||
28 | * time. */ | ||
29 | #define RANDOM_DATA_SIZE 64 | ||
30 | |||
31 | static struct virtqueue *vq; | 27 | static struct virtqueue *vq; |
32 | static u32 *random_data; | 28 | static unsigned int data_avail; |
33 | static unsigned int data_left; | ||
34 | static DECLARE_COMPLETION(have_data); | 29 | static DECLARE_COMPLETION(have_data); |
30 | static bool busy; | ||
35 | 31 | ||
36 | static void random_recv_done(struct virtqueue *vq) | 32 | static void random_recv_done(struct virtqueue *vq) |
37 | { | 33 | { |
38 | unsigned int len; | ||
39 | |||
40 | /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ | 34 | /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ |
41 | if (!vq->vq_ops->get_buf(vq, &len)) | 35 | if (!vq->vq_ops->get_buf(vq, &data_avail)) |
42 | return; | 36 | return; |
43 | 37 | ||
44 | data_left += len; | ||
45 | complete(&have_data); | 38 | complete(&have_data); |
46 | } | 39 | } |
47 | 40 | ||
48 | static void register_buffer(void) | 41 | /* The host will fill any buffer we give it with sweet, sweet randomness. */ |
42 | static void register_buffer(u8 *buf, size_t size) | ||
49 | { | 43 | { |
50 | struct scatterlist sg; | 44 | struct scatterlist sg; |
51 | 45 | ||
52 | sg_init_one(&sg, random_data+data_left, RANDOM_DATA_SIZE-data_left); | 46 | sg_init_one(&sg, buf, size); |
47 | |||
53 | /* There should always be room for one buffer. */ | 48 | /* There should always be room for one buffer. */ |
54 | if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) < 0) | 49 | if (vq->vq_ops->add_buf(vq, &sg, 0, 1, buf) < 0) |
55 | BUG(); | 50 | BUG(); |
51 | |||
56 | vq->vq_ops->kick(vq); | 52 | vq->vq_ops->kick(vq); |
57 | } | 53 | } |
58 | 54 | ||
59 | /* At least we don't udelay() in a loop like some other drivers. */ | 55 | static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) |
60 | static int virtio_data_present(struct hwrng *rng, int wait) | ||
61 | { | 56 | { |
62 | if (data_left >= sizeof(u32)) | ||
63 | return 1; | ||
64 | 57 | ||
65 | again: | 58 | if (!busy) { |
59 | busy = true; | ||
60 | init_completion(&have_data); | ||
61 | register_buffer(buf, size); | ||
62 | } | ||
63 | |||
66 | if (!wait) | 64 | if (!wait) |
67 | return 0; | 65 | return 0; |
68 | 66 | ||
69 | wait_for_completion(&have_data); | 67 | wait_for_completion(&have_data); |
70 | 68 | ||
71 | /* Not enough? Re-register. */ | 69 | busy = false; |
72 | if (unlikely(data_left < sizeof(u32))) { | ||
73 | register_buffer(); | ||
74 | goto again; | ||
75 | } | ||
76 | 70 | ||
77 | return 1; | 71 | return data_avail; |
78 | } | 72 | } |
79 | 73 | ||
80 | /* virtio_data_present() must have succeeded before this is called. */ | 74 | static void virtio_cleanup(struct hwrng *rng) |
81 | static int virtio_data_read(struct hwrng *rng, u32 *data) | ||
82 | { | 75 | { |
83 | BUG_ON(data_left < sizeof(u32)); | 76 | if (busy) |
84 | data_left -= sizeof(u32); | 77 | wait_for_completion(&have_data); |
85 | *data = random_data[data_left / 4]; | ||
86 | |||
87 | if (data_left < sizeof(u32)) { | ||
88 | init_completion(&have_data); | ||
89 | register_buffer(); | ||
90 | } | ||
91 | return sizeof(*data); | ||
92 | } | 78 | } |
93 | 79 | ||
80 | |||
94 | static struct hwrng virtio_hwrng = { | 81 | static struct hwrng virtio_hwrng = { |
95 | .name = "virtio", | 82 | .name = "virtio", |
96 | .data_present = virtio_data_present, | 83 | .cleanup = virtio_cleanup, |
97 | .data_read = virtio_data_read, | 84 | .read = virtio_read, |
98 | }; | 85 | }; |
99 | 86 | ||
100 | static int virtrng_probe(struct virtio_device *vdev) | 87 | static int virtrng_probe(struct virtio_device *vdev) |
@@ -112,7 +99,6 @@ static int virtrng_probe(struct virtio_device *vdev) | |||
112 | return err; | 99 | return err; |
113 | } | 100 | } |
114 | 101 | ||
115 | register_buffer(); | ||
116 | return 0; | 102 | return 0; |
117 | } | 103 | } |
118 | 104 | ||
@@ -138,21 +124,11 @@ static struct virtio_driver virtio_rng = { | |||
138 | 124 | ||
139 | static int __init init(void) | 125 | static int __init init(void) |
140 | { | 126 | { |
141 | int err; | 127 | return register_virtio_driver(&virtio_rng); |
142 | |||
143 | random_data = kmalloc(RANDOM_DATA_SIZE, GFP_KERNEL); | ||
144 | if (!random_data) | ||
145 | return -ENOMEM; | ||
146 | |||
147 | err = register_virtio_driver(&virtio_rng); | ||
148 | if (err) | ||
149 | kfree(random_data); | ||
150 | return err; | ||
151 | } | 128 | } |
152 | 129 | ||
153 | static void __exit fini(void) | 130 | static void __exit fini(void) |
154 | { | 131 | { |
155 | kfree(random_data); | ||
156 | unregister_virtio_driver(&virtio_rng); | 132 | unregister_virtio_driver(&virtio_rng); |
157 | } | 133 | } |
158 | module_init(init); | 134 | module_init(init); |
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c index 80704875794c..cf82fedae099 100644 --- a/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/drivers/char/ipmi/ipmi_kcs_sm.c | |||
@@ -370,7 +370,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) | |||
370 | return SI_SM_IDLE; | 370 | return SI_SM_IDLE; |
371 | 371 | ||
372 | case KCS_START_OP: | 372 | case KCS_START_OP: |
373 | if (state != KCS_IDLE) { | 373 | if (state != KCS_IDLE_STATE) { |
374 | start_error_recovery(kcs, | 374 | start_error_recovery(kcs, |
375 | "State machine not idle at start"); | 375 | "State machine not idle at start"); |
376 | break; | 376 | break; |
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 2e66b5f773dd..0dec5da000ef 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -660,26 +660,23 @@ static struct ipmi_smi_watcher smi_watcher = { | |||
660 | #include <linux/sysctl.h> | 660 | #include <linux/sysctl.h> |
661 | 661 | ||
662 | static ctl_table ipmi_table[] = { | 662 | static ctl_table ipmi_table[] = { |
663 | { .ctl_name = DEV_IPMI_POWEROFF_POWERCYCLE, | 663 | { .procname = "poweroff_powercycle", |
664 | .procname = "poweroff_powercycle", | ||
665 | .data = &poweroff_powercycle, | 664 | .data = &poweroff_powercycle, |
666 | .maxlen = sizeof(poweroff_powercycle), | 665 | .maxlen = sizeof(poweroff_powercycle), |
667 | .mode = 0644, | 666 | .mode = 0644, |
668 | .proc_handler = &proc_dointvec }, | 667 | .proc_handler = proc_dointvec }, |
669 | { } | 668 | { } |
670 | }; | 669 | }; |
671 | 670 | ||
672 | static ctl_table ipmi_dir_table[] = { | 671 | static ctl_table ipmi_dir_table[] = { |
673 | { .ctl_name = DEV_IPMI, | 672 | { .procname = "ipmi", |
674 | .procname = "ipmi", | ||
675 | .mode = 0555, | 673 | .mode = 0555, |
676 | .child = ipmi_table }, | 674 | .child = ipmi_table }, |
677 | { } | 675 | { } |
678 | }; | 676 | }; |
679 | 677 | ||
680 | static ctl_table ipmi_root_table[] = { | 678 | static ctl_table ipmi_root_table[] = { |
681 | { .ctl_name = CTL_DEV, | 679 | { .procname = "dev", |
682 | .procname = "dev", | ||
683 | .mode = 0555, | 680 | .mode = 0555, |
684 | .child = ipmi_dir_table }, | 681 | .child = ipmi_dir_table }, |
685 | { } | 682 | { } |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index d2e698096ace..176f1751237f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/dmi.h> | 64 | #include <linux/dmi.h> |
65 | #include <linux/string.h> | 65 | #include <linux/string.h> |
66 | #include <linux/ctype.h> | 66 | #include <linux/ctype.h> |
67 | #include <linux/pnp.h> | ||
67 | 68 | ||
68 | #ifdef CONFIG_PPC_OF | 69 | #ifdef CONFIG_PPC_OF |
69 | #include <linux/of_device.h> | 70 | #include <linux/of_device.h> |
@@ -1919,7 +1920,7 @@ struct SPMITable { | |||
1919 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ | 1920 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ |
1920 | }; | 1921 | }; |
1921 | 1922 | ||
1922 | static __devinit int try_init_acpi(struct SPMITable *spmi) | 1923 | static __devinit int try_init_spmi(struct SPMITable *spmi) |
1923 | { | 1924 | { |
1924 | struct smi_info *info; | 1925 | struct smi_info *info; |
1925 | u8 addr_space; | 1926 | u8 addr_space; |
@@ -1940,7 +1941,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) | |||
1940 | return -ENOMEM; | 1941 | return -ENOMEM; |
1941 | } | 1942 | } |
1942 | 1943 | ||
1943 | info->addr_source = "ACPI"; | 1944 | info->addr_source = "SPMI"; |
1944 | 1945 | ||
1945 | /* Figure out the interface type. */ | 1946 | /* Figure out the interface type. */ |
1946 | switch (spmi->InterfaceType) { | 1947 | switch (spmi->InterfaceType) { |
@@ -2002,7 +2003,7 @@ static __devinit int try_init_acpi(struct SPMITable *spmi) | |||
2002 | return 0; | 2003 | return 0; |
2003 | } | 2004 | } |
2004 | 2005 | ||
2005 | static __devinit void acpi_find_bmc(void) | 2006 | static __devinit void spmi_find_bmc(void) |
2006 | { | 2007 | { |
2007 | acpi_status status; | 2008 | acpi_status status; |
2008 | struct SPMITable *spmi; | 2009 | struct SPMITable *spmi; |
@@ -2020,9 +2021,106 @@ static __devinit void acpi_find_bmc(void) | |||
2020 | if (status != AE_OK) | 2021 | if (status != AE_OK) |
2021 | return; | 2022 | return; |
2022 | 2023 | ||
2023 | try_init_acpi(spmi); | 2024 | try_init_spmi(spmi); |
2024 | } | 2025 | } |
2025 | } | 2026 | } |
2027 | |||
2028 | static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | ||
2029 | const struct pnp_device_id *dev_id) | ||
2030 | { | ||
2031 | struct acpi_device *acpi_dev; | ||
2032 | struct smi_info *info; | ||
2033 | acpi_handle handle; | ||
2034 | acpi_status status; | ||
2035 | unsigned long long tmp; | ||
2036 | |||
2037 | acpi_dev = pnp_acpi_device(dev); | ||
2038 | if (!acpi_dev) | ||
2039 | return -ENODEV; | ||
2040 | |||
2041 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
2042 | if (!info) | ||
2043 | return -ENOMEM; | ||
2044 | |||
2045 | info->addr_source = "ACPI"; | ||
2046 | |||
2047 | handle = acpi_dev->handle; | ||
2048 | |||
2049 | /* _IFT tells us the interface type: KCS, BT, etc */ | ||
2050 | status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); | ||
2051 | if (ACPI_FAILURE(status)) | ||
2052 | goto err_free; | ||
2053 | |||
2054 | switch (tmp) { | ||
2055 | case 1: | ||
2056 | info->si_type = SI_KCS; | ||
2057 | break; | ||
2058 | case 2: | ||
2059 | info->si_type = SI_SMIC; | ||
2060 | break; | ||
2061 | case 3: | ||
2062 | info->si_type = SI_BT; | ||
2063 | break; | ||
2064 | default: | ||
2065 | dev_info(&dev->dev, "unknown interface type %lld\n", tmp); | ||
2066 | goto err_free; | ||
2067 | } | ||
2068 | |||
2069 | if (pnp_port_valid(dev, 0)) { | ||
2070 | info->io_setup = port_setup; | ||
2071 | info->io.addr_type = IPMI_IO_ADDR_SPACE; | ||
2072 | info->io.addr_data = pnp_port_start(dev, 0); | ||
2073 | } else if (pnp_mem_valid(dev, 0)) { | ||
2074 | info->io_setup = mem_setup; | ||
2075 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; | ||
2076 | info->io.addr_data = pnp_mem_start(dev, 0); | ||
2077 | } else { | ||
2078 | dev_err(&dev->dev, "no I/O or memory address\n"); | ||
2079 | goto err_free; | ||
2080 | } | ||
2081 | |||
2082 | info->io.regspacing = DEFAULT_REGSPACING; | ||
2083 | info->io.regsize = DEFAULT_REGSPACING; | ||
2084 | info->io.regshift = 0; | ||
2085 | |||
2086 | /* If _GPE exists, use it; otherwise use standard interrupts */ | ||
2087 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); | ||
2088 | if (ACPI_SUCCESS(status)) { | ||
2089 | info->irq = tmp; | ||
2090 | info->irq_setup = acpi_gpe_irq_setup; | ||
2091 | } else if (pnp_irq_valid(dev, 0)) { | ||
2092 | info->irq = pnp_irq(dev, 0); | ||
2093 | info->irq_setup = std_irq_setup; | ||
2094 | } | ||
2095 | |||
2096 | info->dev = &acpi_dev->dev; | ||
2097 | pnp_set_drvdata(dev, info); | ||
2098 | |||
2099 | return try_smi_init(info); | ||
2100 | |||
2101 | err_free: | ||
2102 | kfree(info); | ||
2103 | return -EINVAL; | ||
2104 | } | ||
2105 | |||
2106 | static void __devexit ipmi_pnp_remove(struct pnp_dev *dev) | ||
2107 | { | ||
2108 | struct smi_info *info = pnp_get_drvdata(dev); | ||
2109 | |||
2110 | cleanup_one_si(info); | ||
2111 | } | ||
2112 | |||
2113 | static const struct pnp_device_id pnp_dev_table[] = { | ||
2114 | {"IPI0001", 0}, | ||
2115 | {"", 0}, | ||
2116 | }; | ||
2117 | |||
2118 | static struct pnp_driver ipmi_pnp_driver = { | ||
2119 | .name = DEVICE_NAME, | ||
2120 | .probe = ipmi_pnp_probe, | ||
2121 | .remove = __devexit_p(ipmi_pnp_remove), | ||
2122 | .id_table = pnp_dev_table, | ||
2123 | }; | ||
2026 | #endif | 2124 | #endif |
2027 | 2125 | ||
2028 | #ifdef CONFIG_DMI | 2126 | #ifdef CONFIG_DMI |
@@ -2202,7 +2300,6 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2202 | int rv; | 2300 | int rv; |
2203 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; | 2301 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; |
2204 | struct smi_info *info; | 2302 | struct smi_info *info; |
2205 | int first_reg_offset = 0; | ||
2206 | 2303 | ||
2207 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2304 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
2208 | if (!info) | 2305 | if (!info) |
@@ -2241,9 +2338,6 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2241 | info->addr_source_cleanup = ipmi_pci_cleanup; | 2338 | info->addr_source_cleanup = ipmi_pci_cleanup; |
2242 | info->addr_source_data = pdev; | 2339 | info->addr_source_data = pdev; |
2243 | 2340 | ||
2244 | if (pdev->subsystem_vendor == PCI_HP_VENDOR_ID) | ||
2245 | first_reg_offset = 1; | ||
2246 | |||
2247 | if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { | 2341 | if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { |
2248 | info->io_setup = port_setup; | 2342 | info->io_setup = port_setup; |
2249 | info->io.addr_type = IPMI_IO_ADDR_SPACE; | 2343 | info->io.addr_type = IPMI_IO_ADDR_SPACE; |
@@ -3108,7 +3202,10 @@ static __devinit int init_ipmi_si(void) | |||
3108 | #endif | 3202 | #endif |
3109 | 3203 | ||
3110 | #ifdef CONFIG_ACPI | 3204 | #ifdef CONFIG_ACPI |
3111 | acpi_find_bmc(); | 3205 | spmi_find_bmc(); |
3206 | #endif | ||
3207 | #ifdef CONFIG_ACPI | ||
3208 | pnp_register_driver(&ipmi_pnp_driver); | ||
3112 | #endif | 3209 | #endif |
3113 | 3210 | ||
3114 | #ifdef CONFIG_PCI | 3211 | #ifdef CONFIG_PCI |
@@ -3233,6 +3330,9 @@ static __exit void cleanup_ipmi_si(void) | |||
3233 | #ifdef CONFIG_PCI | 3330 | #ifdef CONFIG_PCI |
3234 | pci_unregister_driver(&ipmi_pci_driver); | 3331 | pci_unregister_driver(&ipmi_pci_driver); |
3235 | #endif | 3332 | #endif |
3333 | #ifdef CONFIG_ACPI | ||
3334 | pnp_unregister_driver(&ipmi_pnp_driver); | ||
3335 | #endif | ||
3236 | 3336 | ||
3237 | #ifdef CONFIG_PPC_OF | 3337 | #ifdef CONFIG_PPC_OF |
3238 | of_unregister_platform_driver(&ipmi_of_platform_driver); | 3338 | of_unregister_platform_driver(&ipmi_of_platform_driver); |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 426bfdd7f3e0..300d5bd6cd06 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -793,35 +793,30 @@ static inline void isicom_setup_board(struct isi_board *bp) | |||
793 | { | 793 | { |
794 | int channel; | 794 | int channel; |
795 | struct isi_port *port; | 795 | struct isi_port *port; |
796 | unsigned long flags; | ||
797 | 796 | ||
798 | spin_lock_irqsave(&bp->card_lock, flags); | 797 | bp->count++; |
799 | if (bp->status & BOARD_ACTIVE) { | 798 | if (!(bp->status & BOARD_INIT)) { |
800 | spin_unlock_irqrestore(&bp->card_lock, flags); | 799 | port = bp->ports; |
801 | return; | 800 | for (channel = 0; channel < bp->port_count; channel++, port++) |
801 | drop_dtr_rts(port); | ||
802 | } | 802 | } |
803 | port = bp->ports; | 803 | bp->status |= BOARD_ACTIVE | BOARD_INIT; |
804 | bp->status |= BOARD_ACTIVE; | ||
805 | for (channel = 0; channel < bp->port_count; channel++, port++) | ||
806 | drop_dtr_rts(port); | ||
807 | spin_unlock_irqrestore(&bp->card_lock, flags); | ||
808 | } | 804 | } |
809 | 805 | ||
810 | static int isicom_setup_port(struct tty_struct *tty) | 806 | /* Activate and thus setup board are protected from races against shutdown |
807 | by the tty_port mutex */ | ||
808 | |||
809 | static int isicom_activate(struct tty_port *tport, struct tty_struct *tty) | ||
811 | { | 810 | { |
812 | struct isi_port *port = tty->driver_data; | 811 | struct isi_port *port = container_of(tport, struct isi_port, port); |
813 | struct isi_board *card = port->card; | 812 | struct isi_board *card = port->card; |
814 | unsigned long flags; | 813 | unsigned long flags; |
815 | 814 | ||
816 | if (port->port.flags & ASYNC_INITIALIZED) | 815 | if (tty_port_alloc_xmit_buf(tport) < 0) |
817 | return 0; | ||
818 | if (tty_port_alloc_xmit_buf(&port->port) < 0) | ||
819 | return -ENOMEM; | 816 | return -ENOMEM; |
820 | 817 | ||
821 | spin_lock_irqsave(&card->card_lock, flags); | 818 | spin_lock_irqsave(&card->card_lock, flags); |
822 | clear_bit(TTY_IO_ERROR, &tty->flags); | 819 | isicom_setup_board(card); |
823 | if (port->port.count == 1) | ||
824 | card->count++; | ||
825 | 820 | ||
826 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 821 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
827 | 822 | ||
@@ -832,9 +827,7 @@ static int isicom_setup_port(struct tty_struct *tty) | |||
832 | outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base); | 827 | outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base); |
833 | InterruptTheCard(card->base); | 828 | InterruptTheCard(card->base); |
834 | } | 829 | } |
835 | |||
836 | isicom_config_port(tty); | 830 | isicom_config_port(tty); |
837 | port->port.flags |= ASYNC_INITIALIZED; | ||
838 | spin_unlock_irqrestore(&card->card_lock, flags); | 831 | spin_unlock_irqrestore(&card->card_lock, flags); |
839 | 832 | ||
840 | return 0; | 833 | return 0; |
@@ -871,85 +864,37 @@ static struct tty_port *isicom_find_port(struct tty_struct *tty) | |||
871 | 864 | ||
872 | return &port->port; | 865 | return &port->port; |
873 | } | 866 | } |
874 | 867 | ||
875 | static int isicom_open(struct tty_struct *tty, struct file *filp) | 868 | static int isicom_open(struct tty_struct *tty, struct file *filp) |
876 | { | 869 | { |
877 | struct isi_port *port; | 870 | struct isi_port *port; |
878 | struct isi_board *card; | 871 | struct isi_board *card; |
879 | struct tty_port *tport; | 872 | struct tty_port *tport; |
880 | int error = 0; | ||
881 | 873 | ||
882 | tport = isicom_find_port(tty); | 874 | tport = isicom_find_port(tty); |
883 | if (tport == NULL) | 875 | if (tport == NULL) |
884 | return -ENODEV; | 876 | return -ENODEV; |
885 | port = container_of(tport, struct isi_port, port); | 877 | port = container_of(tport, struct isi_port, port); |
886 | card = &isi_card[BOARD(tty->index)]; | 878 | card = &isi_card[BOARD(tty->index)]; |
887 | isicom_setup_board(card); | ||
888 | 879 | ||
889 | /* FIXME: locking on port.count etc */ | 880 | return tty_port_open(tport, tty, filp); |
890 | port->port.count++; | ||
891 | tty->driver_data = port; | ||
892 | tty_port_tty_set(&port->port, tty); | ||
893 | /* FIXME: Locking on Initialized flag */ | ||
894 | if (!test_bit(ASYNCB_INITIALIZED, &tport->flags)) | ||
895 | error = isicom_setup_port(tty); | ||
896 | if (error == 0) | ||
897 | error = tty_port_block_til_ready(&port->port, tty, filp); | ||
898 | return error; | ||
899 | } | 881 | } |
900 | 882 | ||
901 | /* close et all */ | 883 | /* close et all */ |
902 | 884 | ||
903 | static inline void isicom_shutdown_board(struct isi_board *bp) | ||
904 | { | ||
905 | if (bp->status & BOARD_ACTIVE) | ||
906 | bp->status &= ~BOARD_ACTIVE; | ||
907 | } | ||
908 | |||
909 | /* card->lock HAS to be held */ | 885 | /* card->lock HAS to be held */ |
910 | static void isicom_shutdown_port(struct isi_port *port) | 886 | static void isicom_shutdown_port(struct isi_port *port) |
911 | { | 887 | { |
912 | struct isi_board *card = port->card; | 888 | struct isi_board *card = port->card; |
913 | struct tty_struct *tty; | ||
914 | |||
915 | tty = tty_port_tty_get(&port->port); | ||
916 | |||
917 | if (!(port->port.flags & ASYNC_INITIALIZED)) { | ||
918 | tty_kref_put(tty); | ||
919 | return; | ||
920 | } | ||
921 | |||
922 | tty_port_free_xmit_buf(&port->port); | ||
923 | port->port.flags &= ~ASYNC_INITIALIZED; | ||
924 | /* 3rd October 2000 : Vinayak P Risbud */ | ||
925 | tty_port_tty_set(&port->port, NULL); | ||
926 | |||
927 | /*Fix done by Anil .S on 30-04-2001 | ||
928 | remote login through isi port has dtr toggle problem | ||
929 | due to which the carrier drops before the password prompt | ||
930 | appears on the remote end. Now we drop the dtr only if the | ||
931 | HUPCL(Hangup on close) flag is set for the tty*/ | ||
932 | |||
933 | if (C_HUPCL(tty)) | ||
934 | /* drop dtr on this port */ | ||
935 | drop_dtr(port); | ||
936 | |||
937 | /* any other port uninits */ | ||
938 | if (tty) | ||
939 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
940 | 889 | ||
941 | if (--card->count < 0) { | 890 | if (--card->count < 0) { |
942 | pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n", | 891 | pr_dbg("isicom_shutdown_port: bad board(0x%lx) count %d.\n", |
943 | card->base, card->count); | 892 | card->base, card->count); |
944 | card->count = 0; | 893 | card->count = 0; |
945 | } | 894 | } |
946 | 895 | /* last port was closed, shutdown that board too */ | |
947 | /* last port was closed, shutdown that boad too */ | 896 | if (!card->count) |
948 | if (C_HUPCL(tty)) { | 897 | card->status &= BOARD_ACTIVE; |
949 | if (!card->count) | ||
950 | isicom_shutdown_board(card); | ||
951 | } | ||
952 | tty_kref_put(tty); | ||
953 | } | 898 | } |
954 | 899 | ||
955 | static void isicom_flush_buffer(struct tty_struct *tty) | 900 | static void isicom_flush_buffer(struct tty_struct *tty) |
@@ -968,7 +913,7 @@ static void isicom_flush_buffer(struct tty_struct *tty) | |||
968 | tty_wakeup(tty); | 913 | tty_wakeup(tty); |
969 | } | 914 | } |
970 | 915 | ||
971 | static void isicom_close_port(struct tty_port *port) | 916 | static void isicom_shutdown(struct tty_port *port) |
972 | { | 917 | { |
973 | struct isi_port *ip = container_of(port, struct isi_port, port); | 918 | struct isi_port *ip = container_of(port, struct isi_port, port); |
974 | struct isi_board *card = ip->card; | 919 | struct isi_board *card = ip->card; |
@@ -977,12 +922,11 @@ static void isicom_close_port(struct tty_port *port) | |||
977 | /* indicate to the card that no more data can be received | 922 | /* indicate to the card that no more data can be received |
978 | on this port */ | 923 | on this port */ |
979 | spin_lock_irqsave(&card->card_lock, flags); | 924 | spin_lock_irqsave(&card->card_lock, flags); |
980 | if (port->flags & ASYNC_INITIALIZED) { | 925 | card->port_status &= ~(1 << ip->channel); |
981 | card->port_status &= ~(1 << ip->channel); | 926 | outw(card->port_status, card->base + 0x02); |
982 | outw(card->port_status, card->base + 0x02); | ||
983 | } | ||
984 | isicom_shutdown_port(ip); | 927 | isicom_shutdown_port(ip); |
985 | spin_unlock_irqrestore(&card->card_lock, flags); | 928 | spin_unlock_irqrestore(&card->card_lock, flags); |
929 | tty_port_free_xmit_buf(port); | ||
986 | } | 930 | } |
987 | 931 | ||
988 | static void isicom_close(struct tty_struct *tty, struct file *filp) | 932 | static void isicom_close(struct tty_struct *tty, struct file *filp) |
@@ -991,12 +935,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp) | |||
991 | struct tty_port *port = &ip->port; | 935 | struct tty_port *port = &ip->port; |
992 | if (isicom_paranoia_check(ip, tty->name, "isicom_close")) | 936 | if (isicom_paranoia_check(ip, tty->name, "isicom_close")) |
993 | return; | 937 | return; |
994 | 938 | tty_port_close(port, tty, filp); | |
995 | if (tty_port_close_start(port, tty, filp) == 0) | ||
996 | return; | ||
997 | isicom_close_port(port); | ||
998 | isicom_flush_buffer(tty); | ||
999 | tty_port_close_end(port, tty); | ||
1000 | } | 939 | } |
1001 | 940 | ||
1002 | /* write et all */ | 941 | /* write et all */ |
@@ -1326,15 +1265,9 @@ static void isicom_start(struct tty_struct *tty) | |||
1326 | static void isicom_hangup(struct tty_struct *tty) | 1265 | static void isicom_hangup(struct tty_struct *tty) |
1327 | { | 1266 | { |
1328 | struct isi_port *port = tty->driver_data; | 1267 | struct isi_port *port = tty->driver_data; |
1329 | unsigned long flags; | ||
1330 | 1268 | ||
1331 | if (isicom_paranoia_check(port, tty->name, "isicom_hangup")) | 1269 | if (isicom_paranoia_check(port, tty->name, "isicom_hangup")) |
1332 | return; | 1270 | return; |
1333 | |||
1334 | spin_lock_irqsave(&port->card->card_lock, flags); | ||
1335 | isicom_shutdown_port(port); | ||
1336 | spin_unlock_irqrestore(&port->card->card_lock, flags); | ||
1337 | |||
1338 | tty_port_hangup(&port->port); | 1271 | tty_port_hangup(&port->port); |
1339 | } | 1272 | } |
1340 | 1273 | ||
@@ -1367,6 +1300,8 @@ static const struct tty_operations isicom_ops = { | |||
1367 | static const struct tty_port_operations isicom_port_ops = { | 1300 | static const struct tty_port_operations isicom_port_ops = { |
1368 | .carrier_raised = isicom_carrier_raised, | 1301 | .carrier_raised = isicom_carrier_raised, |
1369 | .dtr_rts = isicom_dtr_rts, | 1302 | .dtr_rts = isicom_dtr_rts, |
1303 | .activate = isicom_activate, | ||
1304 | .shutdown = isicom_shutdown, | ||
1370 | }; | 1305 | }; |
1371 | 1306 | ||
1372 | static int __devinit reset_card(struct pci_dev *pdev, | 1307 | static int __devinit reset_card(struct pci_dev *pdev, |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 402838f4083e..4cd6c527ee41 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -213,7 +213,6 @@ static int stli_shared; | |||
213 | * with the slave. Most of them need to be updated atomically, so always | 213 | * with the slave. Most of them need to be updated atomically, so always |
214 | * use the bit setting operations (unless protected by cli/sti). | 214 | * use the bit setting operations (unless protected by cli/sti). |
215 | */ | 215 | */ |
216 | #define ST_INITIALIZING 1 | ||
217 | #define ST_OPENING 2 | 216 | #define ST_OPENING 2 |
218 | #define ST_CLOSING 3 | 217 | #define ST_CLOSING 3 |
219 | #define ST_CMDING 4 | 218 | #define ST_CMDING 4 |
@@ -621,7 +620,7 @@ static int stli_brdinit(struct stlibrd *brdp); | |||
621 | static int stli_startbrd(struct stlibrd *brdp); | 620 | static int stli_startbrd(struct stlibrd *brdp); |
622 | static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); | 621 | static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); |
623 | static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); | 622 | static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); |
624 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); | 623 | static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); |
625 | static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); | 624 | static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); |
626 | static void stli_poll(unsigned long arg); | 625 | static void stli_poll(unsigned long arg); |
627 | static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); | 626 | static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); |
@@ -704,7 +703,7 @@ static const struct file_operations stli_fsiomem = { | |||
704 | .owner = THIS_MODULE, | 703 | .owner = THIS_MODULE, |
705 | .read = stli_memread, | 704 | .read = stli_memread, |
706 | .write = stli_memwrite, | 705 | .write = stli_memwrite, |
707 | .ioctl = stli_memioctl, | 706 | .unlocked_ioctl = stli_memioctl, |
708 | }; | 707 | }; |
709 | 708 | ||
710 | /*****************************************************************************/ | 709 | /*****************************************************************************/ |
@@ -783,13 +782,32 @@ static int stli_parsebrd(struct stlconf *confp, char **argp) | |||
783 | 782 | ||
784 | /*****************************************************************************/ | 783 | /*****************************************************************************/ |
785 | 784 | ||
785 | /* | ||
786 | * On the first open of the device setup the port hardware, and | ||
787 | * initialize the per port data structure. Since initializing the port | ||
788 | * requires several commands to the board we will need to wait for any | ||
789 | * other open that is already initializing the port. | ||
790 | * | ||
791 | * Locking: protected by the port mutex. | ||
792 | */ | ||
793 | |||
794 | static int stli_activate(struct tty_port *port, struct tty_struct *tty) | ||
795 | { | ||
796 | struct stliport *portp = container_of(port, struct stliport, port); | ||
797 | struct stlibrd *brdp = stli_brds[portp->brdnr]; | ||
798 | int rc; | ||
799 | |||
800 | if ((rc = stli_initopen(tty, brdp, portp)) >= 0) | ||
801 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
802 | wake_up_interruptible(&portp->raw_wait); | ||
803 | return rc; | ||
804 | } | ||
805 | |||
786 | static int stli_open(struct tty_struct *tty, struct file *filp) | 806 | static int stli_open(struct tty_struct *tty, struct file *filp) |
787 | { | 807 | { |
788 | struct stlibrd *brdp; | 808 | struct stlibrd *brdp; |
789 | struct stliport *portp; | 809 | struct stliport *portp; |
790 | struct tty_port *port; | ||
791 | unsigned int minordev, brdnr, portnr; | 810 | unsigned int minordev, brdnr, portnr; |
792 | int rc; | ||
793 | 811 | ||
794 | minordev = tty->index; | 812 | minordev = tty->index; |
795 | brdnr = MINOR2BRD(minordev); | 813 | brdnr = MINOR2BRD(minordev); |
@@ -809,95 +827,56 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
809 | return -ENODEV; | 827 | return -ENODEV; |
810 | if (portp->devnr < 1) | 828 | if (portp->devnr < 1) |
811 | return -ENODEV; | 829 | return -ENODEV; |
812 | port = &portp->port; | 830 | return tty_port_open(&portp->port, tty, filp); |
813 | |||
814 | /* | ||
815 | * On the first open of the device setup the port hardware, and | ||
816 | * initialize the per port data structure. Since initializing the port | ||
817 | * requires several commands to the board we will need to wait for any | ||
818 | * other open that is already initializing the port. | ||
819 | * | ||
820 | * Review - locking | ||
821 | */ | ||
822 | tty_port_tty_set(port, tty); | ||
823 | tty->driver_data = portp; | ||
824 | port->count++; | ||
825 | |||
826 | wait_event_interruptible(portp->raw_wait, | ||
827 | !test_bit(ST_INITIALIZING, &portp->state)); | ||
828 | if (signal_pending(current)) | ||
829 | return -ERESTARTSYS; | ||
830 | |||
831 | if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { | ||
832 | set_bit(ST_INITIALIZING, &portp->state); | ||
833 | if ((rc = stli_initopen(tty, brdp, portp)) >= 0) { | ||
834 | /* Locking */ | ||
835 | port->flags |= ASYNC_INITIALIZED; | ||
836 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
837 | } | ||
838 | clear_bit(ST_INITIALIZING, &portp->state); | ||
839 | wake_up_interruptible(&portp->raw_wait); | ||
840 | if (rc < 0) | ||
841 | return rc; | ||
842 | } | ||
843 | return tty_port_block_til_ready(&portp->port, tty, filp); | ||
844 | } | 831 | } |
845 | 832 | ||
833 | |||
846 | /*****************************************************************************/ | 834 | /*****************************************************************************/ |
847 | 835 | ||
848 | static void stli_close(struct tty_struct *tty, struct file *filp) | 836 | static void stli_shutdown(struct tty_port *port) |
849 | { | 837 | { |
850 | struct stlibrd *brdp; | 838 | struct stlibrd *brdp; |
851 | struct stliport *portp; | 839 | unsigned long ftype; |
852 | struct tty_port *port; | ||
853 | unsigned long flags; | 840 | unsigned long flags; |
841 | struct stliport *portp = container_of(port, struct stliport, port); | ||
854 | 842 | ||
855 | portp = tty->driver_data; | 843 | if (portp->brdnr >= stli_nrbrds) |
856 | if (portp == NULL) | ||
857 | return; | 844 | return; |
858 | port = &portp->port; | 845 | brdp = stli_brds[portp->brdnr]; |
859 | 846 | if (brdp == NULL) | |
860 | if (tty_port_close_start(port, tty, filp) == 0) | ||
861 | return; | 847 | return; |
862 | 848 | ||
863 | /* | 849 | /* |
864 | * May want to wait for data to drain before closing. The BUSY flag | 850 | * May want to wait for data to drain before closing. The BUSY |
865 | * keeps track of whether we are still transmitting or not. It is | 851 | * flag keeps track of whether we are still transmitting or not. |
866 | * updated by messages from the slave - indicating when all chars | 852 | * It is updated by messages from the slave - indicating when all |
867 | * really have drained. | 853 | * chars really have drained. |
868 | */ | 854 | */ |
869 | spin_lock_irqsave(&stli_lock, flags); | ||
870 | if (tty == stli_txcooktty) | ||
871 | stli_flushchars(tty); | ||
872 | spin_unlock_irqrestore(&stli_lock, flags); | ||
873 | |||
874 | /* We end up doing this twice for the moment. This needs looking at | ||
875 | eventually. Note we still use portp->closing_wait as a result */ | ||
876 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
877 | tty_wait_until_sent(tty, portp->closing_wait); | ||
878 | 855 | ||
879 | /* FIXME: port locking here needs attending to */ | 856 | if (!test_bit(ST_CLOSING, &portp->state)) |
880 | port->flags &= ~ASYNC_INITIALIZED; | 857 | stli_rawclose(brdp, portp, 0, 0); |
881 | 858 | ||
882 | brdp = stli_brds[portp->brdnr]; | 859 | spin_lock_irqsave(&stli_lock, flags); |
883 | stli_rawclose(brdp, portp, 0, 0); | ||
884 | if (tty->termios->c_cflag & HUPCL) { | ||
885 | stli_mkasysigs(&portp->asig, 0, 0); | ||
886 | if (test_bit(ST_CMDING, &portp->state)) | ||
887 | set_bit(ST_DOSIGS, &portp->state); | ||
888 | else | ||
889 | stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig, | ||
890 | sizeof(asysigs_t), 0); | ||
891 | } | ||
892 | clear_bit(ST_TXBUSY, &portp->state); | 860 | clear_bit(ST_TXBUSY, &portp->state); |
893 | clear_bit(ST_RXSTOP, &portp->state); | 861 | clear_bit(ST_RXSTOP, &portp->state); |
894 | set_bit(TTY_IO_ERROR, &tty->flags); | 862 | spin_unlock_irqrestore(&stli_lock, flags); |
895 | tty_ldisc_flush(tty); | ||
896 | set_bit(ST_DOFLUSHRX, &portp->state); | ||
897 | stli_flushbuffer(tty); | ||
898 | 863 | ||
899 | tty_port_close_end(port, tty); | 864 | ftype = FLUSHTX | FLUSHRX; |
900 | tty_port_tty_set(port, NULL); | 865 | stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); |
866 | } | ||
867 | |||
868 | static void stli_close(struct tty_struct *tty, struct file *filp) | ||
869 | { | ||
870 | struct stliport *portp = tty->driver_data; | ||
871 | unsigned long flags; | ||
872 | if (portp == NULL) | ||
873 | return; | ||
874 | spin_lock_irqsave(&stli_lock, flags); | ||
875 | /* Flush any internal buffering out first */ | ||
876 | if (tty == stli_txcooktty) | ||
877 | stli_flushchars(tty); | ||
878 | spin_unlock_irqrestore(&stli_lock, flags); | ||
879 | tty_port_close(&portp->port, tty, filp); | ||
901 | } | 880 | } |
902 | 881 | ||
903 | /*****************************************************************************/ | 882 | /*****************************************************************************/ |
@@ -1724,6 +1703,7 @@ static void stli_start(struct tty_struct *tty) | |||
1724 | 1703 | ||
1725 | /*****************************************************************************/ | 1704 | /*****************************************************************************/ |
1726 | 1705 | ||
1706 | |||
1727 | /* | 1707 | /* |
1728 | * Hangup this port. This is pretty much like closing the port, only | 1708 | * Hangup this port. This is pretty much like closing the port, only |
1729 | * a little more brutal. No waiting for data to drain. Shutdown the | 1709 | * a little more brutal. No waiting for data to drain. Shutdown the |
@@ -1733,47 +1713,8 @@ static void stli_start(struct tty_struct *tty) | |||
1733 | 1713 | ||
1734 | static void stli_hangup(struct tty_struct *tty) | 1714 | static void stli_hangup(struct tty_struct *tty) |
1735 | { | 1715 | { |
1736 | struct stliport *portp; | 1716 | struct stliport *portp = tty->driver_data; |
1737 | struct stlibrd *brdp; | 1717 | tty_port_hangup(&portp->port); |
1738 | struct tty_port *port; | ||
1739 | unsigned long flags; | ||
1740 | |||
1741 | portp = tty->driver_data; | ||
1742 | if (portp == NULL) | ||
1743 | return; | ||
1744 | if (portp->brdnr >= stli_nrbrds) | ||
1745 | return; | ||
1746 | brdp = stli_brds[portp->brdnr]; | ||
1747 | if (brdp == NULL) | ||
1748 | return; | ||
1749 | port = &portp->port; | ||
1750 | |||
1751 | spin_lock_irqsave(&port->lock, flags); | ||
1752 | port->flags &= ~ASYNC_INITIALIZED; | ||
1753 | spin_unlock_irqrestore(&port->lock, flags); | ||
1754 | |||
1755 | if (!test_bit(ST_CLOSING, &portp->state)) | ||
1756 | stli_rawclose(brdp, portp, 0, 0); | ||
1757 | |||
1758 | spin_lock_irqsave(&stli_lock, flags); | ||
1759 | if (tty->termios->c_cflag & HUPCL) { | ||
1760 | stli_mkasysigs(&portp->asig, 0, 0); | ||
1761 | if (test_bit(ST_CMDING, &portp->state)) { | ||
1762 | set_bit(ST_DOSIGS, &portp->state); | ||
1763 | set_bit(ST_DOFLUSHTX, &portp->state); | ||
1764 | set_bit(ST_DOFLUSHRX, &portp->state); | ||
1765 | } else { | ||
1766 | stli_sendcmd(brdp, portp, A_SETSIGNALSF, | ||
1767 | &portp->asig, sizeof(asysigs_t), 0); | ||
1768 | } | ||
1769 | } | ||
1770 | |||
1771 | clear_bit(ST_TXBUSY, &portp->state); | ||
1772 | clear_bit(ST_RXSTOP, &portp->state); | ||
1773 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
1774 | spin_unlock_irqrestore(&stli_lock, flags); | ||
1775 | |||
1776 | tty_port_hangup(port); | ||
1777 | } | 1718 | } |
1778 | 1719 | ||
1779 | /*****************************************************************************/ | 1720 | /*****************************************************************************/ |
@@ -4311,7 +4252,7 @@ static int stli_getbrdstruct(struct stlibrd __user *arg) | |||
4311 | * reset it, and start/stop it. | 4252 | * reset it, and start/stop it. |
4312 | */ | 4253 | */ |
4313 | 4254 | ||
4314 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) | 4255 | static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) |
4315 | { | 4256 | { |
4316 | struct stlibrd *brdp; | 4257 | struct stlibrd *brdp; |
4317 | int brdnr, rc, done; | 4258 | int brdnr, rc, done; |
@@ -4356,7 +4297,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un | |||
4356 | * Now handle the board specific ioctls. These all depend on the | 4297 | * Now handle the board specific ioctls. These all depend on the |
4357 | * minor number of the device they were called from. | 4298 | * minor number of the device they were called from. |
4358 | */ | 4299 | */ |
4359 | brdnr = iminor(ip); | 4300 | brdnr = iminor(fp->f_dentry->d_inode); |
4360 | if (brdnr >= STL_MAXBRDS) | 4301 | if (brdnr >= STL_MAXBRDS) |
4361 | return -ENODEV; | 4302 | return -ENODEV; |
4362 | brdp = stli_brds[brdnr]; | 4303 | brdp = stli_brds[brdnr]; |
@@ -4420,6 +4361,8 @@ static const struct tty_operations stli_ops = { | |||
4420 | static const struct tty_port_operations stli_port_ops = { | 4361 | static const struct tty_port_operations stli_port_ops = { |
4421 | .carrier_raised = stli_carrier_raised, | 4362 | .carrier_raised = stli_carrier_raised, |
4422 | .dtr_rts = stli_dtr_rts, | 4363 | .dtr_rts = stli_dtr_rts, |
4364 | .activate = stli_activate, | ||
4365 | .shutdown = stli_shutdown, | ||
4423 | }; | 4366 | }; |
4424 | 4367 | ||
4425 | /*****************************************************************************/ | 4368 | /*****************************************************************************/ |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 950837cf9e9c..f706b1dffdb3 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -46,8 +46,6 @@ | |||
46 | 46 | ||
47 | extern void ctrl_alt_del(void); | 47 | extern void ctrl_alt_del(void); |
48 | 48 | ||
49 | #define to_handle_h(n) container_of(n, struct input_handle, h_node) | ||
50 | |||
51 | /* | 49 | /* |
52 | * Exported functions/variables | 50 | * Exported functions/variables |
53 | */ | 51 | */ |
@@ -132,6 +130,7 @@ int shift_state = 0; | |||
132 | */ | 130 | */ |
133 | 131 | ||
134 | static struct input_handler kbd_handler; | 132 | static struct input_handler kbd_handler; |
133 | static DEFINE_SPINLOCK(kbd_event_lock); | ||
135 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ | 134 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ |
136 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ | 135 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ |
137 | static int dead_key_next; | 136 | static int dead_key_next; |
@@ -190,78 +189,89 @@ EXPORT_SYMBOL_GPL(unregister_keyboard_notifier); | |||
190 | * etc.). So this means that scancodes for the extra function keys won't | 189 | * etc.). So this means that scancodes for the extra function keys won't |
191 | * be valid for the first event device, but will be for the second. | 190 | * be valid for the first event device, but will be for the second. |
192 | */ | 191 | */ |
192 | |||
193 | struct getset_keycode_data { | ||
194 | unsigned int scancode; | ||
195 | unsigned int keycode; | ||
196 | int error; | ||
197 | }; | ||
198 | |||
199 | static int getkeycode_helper(struct input_handle *handle, void *data) | ||
200 | { | ||
201 | struct getset_keycode_data *d = data; | ||
202 | |||
203 | d->error = input_get_keycode(handle->dev, d->scancode, &d->keycode); | ||
204 | |||
205 | return d->error == 0; /* stop as soon as we successfully get one */ | ||
206 | } | ||
207 | |||
193 | int getkeycode(unsigned int scancode) | 208 | int getkeycode(unsigned int scancode) |
194 | { | 209 | { |
195 | struct input_handle *handle; | 210 | struct getset_keycode_data d = { scancode, 0, -ENODEV }; |
196 | int keycode; | ||
197 | int error = -ENODEV; | ||
198 | 211 | ||
199 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { | 212 | input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper); |
200 | error = input_get_keycode(handle->dev, scancode, &keycode); | ||
201 | if (!error) | ||
202 | return keycode; | ||
203 | } | ||
204 | 213 | ||
205 | return error; | 214 | return d.error ?: d.keycode; |
215 | } | ||
216 | |||
217 | static int setkeycode_helper(struct input_handle *handle, void *data) | ||
218 | { | ||
219 | struct getset_keycode_data *d = data; | ||
220 | |||
221 | d->error = input_set_keycode(handle->dev, d->scancode, d->keycode); | ||
222 | |||
223 | return d->error == 0; /* stop as soon as we successfully set one */ | ||
206 | } | 224 | } |
207 | 225 | ||
208 | int setkeycode(unsigned int scancode, unsigned int keycode) | 226 | int setkeycode(unsigned int scancode, unsigned int keycode) |
209 | { | 227 | { |
210 | struct input_handle *handle; | 228 | struct getset_keycode_data d = { scancode, keycode, -ENODEV }; |
211 | int error = -ENODEV; | ||
212 | 229 | ||
213 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { | 230 | input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper); |
214 | error = input_set_keycode(handle->dev, scancode, keycode); | ||
215 | if (!error) | ||
216 | break; | ||
217 | } | ||
218 | 231 | ||
219 | return error; | 232 | return d.error; |
220 | } | 233 | } |
221 | 234 | ||
222 | /* | 235 | /* |
223 | * Making beeps and bells. | 236 | * Making beeps and bells. Note that we prefer beeps to bells, but when |
237 | * shutting the sound off we do both. | ||
224 | */ | 238 | */ |
225 | static void kd_nosound(unsigned long ignored) | 239 | |
240 | static int kd_sound_helper(struct input_handle *handle, void *data) | ||
226 | { | 241 | { |
227 | struct input_handle *handle; | 242 | unsigned int *hz = data; |
243 | struct input_dev *dev = handle->dev; | ||
228 | 244 | ||
229 | list_for_each_entry(handle, &kbd_handler.h_list, h_node) { | 245 | if (test_bit(EV_SND, dev->evbit)) { |
230 | if (test_bit(EV_SND, handle->dev->evbit)) { | 246 | if (test_bit(SND_TONE, dev->sndbit)) { |
231 | if (test_bit(SND_TONE, handle->dev->sndbit)) | 247 | input_inject_event(handle, EV_SND, SND_TONE, *hz); |
232 | input_inject_event(handle, EV_SND, SND_TONE, 0); | 248 | if (*hz) |
233 | if (test_bit(SND_BELL, handle->dev->sndbit)) | 249 | return 0; |
234 | input_inject_event(handle, EV_SND, SND_BELL, 0); | ||
235 | } | 250 | } |
251 | if (test_bit(SND_BELL, dev->sndbit)) | ||
252 | input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0); | ||
236 | } | 253 | } |
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static void kd_nosound(unsigned long ignored) | ||
259 | { | ||
260 | static unsigned int zero; | ||
261 | |||
262 | input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper); | ||
237 | } | 263 | } |
238 | 264 | ||
239 | static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0); | 265 | static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0); |
240 | 266 | ||
241 | void kd_mksound(unsigned int hz, unsigned int ticks) | 267 | void kd_mksound(unsigned int hz, unsigned int ticks) |
242 | { | 268 | { |
243 | struct list_head *node; | 269 | del_timer_sync(&kd_mksound_timer); |
244 | 270 | ||
245 | del_timer(&kd_mksound_timer); | 271 | input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper); |
246 | 272 | ||
247 | if (hz) { | 273 | if (hz && ticks) |
248 | list_for_each_prev(node, &kbd_handler.h_list) { | 274 | mod_timer(&kd_mksound_timer, jiffies + ticks); |
249 | struct input_handle *handle = to_handle_h(node); | ||
250 | if (test_bit(EV_SND, handle->dev->evbit)) { | ||
251 | if (test_bit(SND_TONE, handle->dev->sndbit)) { | ||
252 | input_inject_event(handle, EV_SND, SND_TONE, hz); | ||
253 | break; | ||
254 | } | ||
255 | if (test_bit(SND_BELL, handle->dev->sndbit)) { | ||
256 | input_inject_event(handle, EV_SND, SND_BELL, 1); | ||
257 | break; | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | if (ticks) | ||
262 | mod_timer(&kd_mksound_timer, jiffies + ticks); | ||
263 | } else | ||
264 | kd_nosound(0); | ||
265 | } | 275 | } |
266 | EXPORT_SYMBOL(kd_mksound); | 276 | EXPORT_SYMBOL(kd_mksound); |
267 | 277 | ||
@@ -269,27 +279,34 @@ EXPORT_SYMBOL(kd_mksound); | |||
269 | * Setting the keyboard rate. | 279 | * Setting the keyboard rate. |
270 | */ | 280 | */ |
271 | 281 | ||
272 | int kbd_rate(struct kbd_repeat *rep) | 282 | static int kbd_rate_helper(struct input_handle *handle, void *data) |
273 | { | 283 | { |
274 | struct list_head *node; | 284 | struct input_dev *dev = handle->dev; |
275 | unsigned int d = 0; | 285 | struct kbd_repeat *rep = data; |
276 | unsigned int p = 0; | 286 | |
277 | 287 | if (test_bit(EV_REP, dev->evbit)) { | |
278 | list_for_each(node, &kbd_handler.h_list) { | 288 | |
279 | struct input_handle *handle = to_handle_h(node); | 289 | if (rep[0].delay > 0) |
280 | struct input_dev *dev = handle->dev; | 290 | input_inject_event(handle, |
281 | 291 | EV_REP, REP_DELAY, rep[0].delay); | |
282 | if (test_bit(EV_REP, dev->evbit)) { | 292 | if (rep[0].period > 0) |
283 | if (rep->delay > 0) | 293 | input_inject_event(handle, |
284 | input_inject_event(handle, EV_REP, REP_DELAY, rep->delay); | 294 | EV_REP, REP_PERIOD, rep[0].period); |
285 | if (rep->period > 0) | 295 | |
286 | input_inject_event(handle, EV_REP, REP_PERIOD, rep->period); | 296 | rep[1].delay = dev->rep[REP_DELAY]; |
287 | d = dev->rep[REP_DELAY]; | 297 | rep[1].period = dev->rep[REP_PERIOD]; |
288 | p = dev->rep[REP_PERIOD]; | ||
289 | } | ||
290 | } | 298 | } |
291 | rep->delay = d; | 299 | |
292 | rep->period = p; | 300 | return 0; |
301 | } | ||
302 | |||
303 | int kbd_rate(struct kbd_repeat *rep) | ||
304 | { | ||
305 | struct kbd_repeat data[2] = { *rep }; | ||
306 | |||
307 | input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper); | ||
308 | *rep = data[1]; /* Copy currently used settings */ | ||
309 | |||
293 | return 0; | 310 | return 0; |
294 | } | 311 | } |
295 | 312 | ||
@@ -997,36 +1014,36 @@ static inline unsigned char getleds(void) | |||
997 | return leds; | 1014 | return leds; |
998 | } | 1015 | } |
999 | 1016 | ||
1017 | static int kbd_update_leds_helper(struct input_handle *handle, void *data) | ||
1018 | { | ||
1019 | unsigned char leds = *(unsigned char *)data; | ||
1020 | |||
1021 | if (test_bit(EV_LED, handle->dev->evbit)) { | ||
1022 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | ||
1023 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1024 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1025 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); | ||
1026 | } | ||
1027 | |||
1028 | return 0; | ||
1029 | } | ||
1030 | |||
1000 | /* | 1031 | /* |
1001 | * This routine is the bottom half of the keyboard interrupt | 1032 | * This is the tasklet that updates LED state on all keyboards |
1002 | * routine, and runs with all interrupts enabled. It does | 1033 | * attached to the box. The reason we use tasklet is that we |
1003 | * console changing, led setting and copy_to_cooked, which can | 1034 | * need to handle the scenario when keyboard handler is not |
1004 | * take a reasonably long time. | 1035 | * registered yet but we already getting updates form VT to |
1005 | * | 1036 | * update led state. |
1006 | * Aside from timing (which isn't really that important for | ||
1007 | * keyboard interrupts as they happen often), using the software | ||
1008 | * interrupt routines for this thing allows us to easily mask | ||
1009 | * this when we don't want any of the above to happen. | ||
1010 | * This allows for easy and efficient race-condition prevention | ||
1011 | * for kbd_start => input_inject_event(dev, EV_LED, ...) => ... | ||
1012 | */ | 1037 | */ |
1013 | |||
1014 | static void kbd_bh(unsigned long dummy) | 1038 | static void kbd_bh(unsigned long dummy) |
1015 | { | 1039 | { |
1016 | struct list_head *node; | ||
1017 | unsigned char leds = getleds(); | 1040 | unsigned char leds = getleds(); |
1018 | 1041 | ||
1019 | if (leds != ledstate) { | 1042 | if (leds != ledstate) { |
1020 | list_for_each(node, &kbd_handler.h_list) { | 1043 | input_handler_for_each_handle(&kbd_handler, &leds, |
1021 | struct input_handle *handle = to_handle_h(node); | 1044 | kbd_update_leds_helper); |
1022 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | 1045 | ledstate = leds; |
1023 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1024 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1025 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); | ||
1026 | } | ||
1027 | } | 1046 | } |
1028 | |||
1029 | ledstate = leds; | ||
1030 | } | 1047 | } |
1031 | 1048 | ||
1032 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); | 1049 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); |
@@ -1136,7 +1153,7 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char u | |||
1136 | static void kbd_rawcode(unsigned char data) | 1153 | static void kbd_rawcode(unsigned char data) |
1137 | { | 1154 | { |
1138 | struct vc_data *vc = vc_cons[fg_console].d; | 1155 | struct vc_data *vc = vc_cons[fg_console].d; |
1139 | kbd = kbd_table + fg_console; | 1156 | kbd = kbd_table + vc->vc_num; |
1140 | if (kbd->kbdmode == VC_RAW) | 1157 | if (kbd->kbdmode == VC_RAW) |
1141 | put_queue(vc, data); | 1158 | put_queue(vc, data); |
1142 | } | 1159 | } |
@@ -1157,7 +1174,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1157 | tty->driver_data = vc; | 1174 | tty->driver_data = vc; |
1158 | } | 1175 | } |
1159 | 1176 | ||
1160 | kbd = kbd_table + fg_console; | 1177 | kbd = kbd_table + vc->vc_num; |
1161 | 1178 | ||
1162 | if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) | 1179 | if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) |
1163 | sysrq_alt = down ? keycode : 0; | 1180 | sysrq_alt = down ? keycode : 0; |
@@ -1296,10 +1313,16 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1296 | static void kbd_event(struct input_handle *handle, unsigned int event_type, | 1313 | static void kbd_event(struct input_handle *handle, unsigned int event_type, |
1297 | unsigned int event_code, int value) | 1314 | unsigned int event_code, int value) |
1298 | { | 1315 | { |
1316 | /* We are called with interrupts disabled, just take the lock */ | ||
1317 | spin_lock(&kbd_event_lock); | ||
1318 | |||
1299 | if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) | 1319 | if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) |
1300 | kbd_rawcode(value); | 1320 | kbd_rawcode(value); |
1301 | if (event_type == EV_KEY) | 1321 | if (event_type == EV_KEY) |
1302 | kbd_keycode(event_code, value, HW_RAW(handle->dev)); | 1322 | kbd_keycode(event_code, value, HW_RAW(handle->dev)); |
1323 | |||
1324 | spin_unlock(&kbd_event_lock); | ||
1325 | |||
1303 | tasklet_schedule(&keyboard_tasklet); | 1326 | tasklet_schedule(&keyboard_tasklet); |
1304 | do_poke_blanked_console = 1; | 1327 | do_poke_blanked_console = 1; |
1305 | schedule_console_callback(); | 1328 | schedule_console_callback(); |
@@ -1363,15 +1386,11 @@ static void kbd_disconnect(struct input_handle *handle) | |||
1363 | */ | 1386 | */ |
1364 | static void kbd_start(struct input_handle *handle) | 1387 | static void kbd_start(struct input_handle *handle) |
1365 | { | 1388 | { |
1366 | unsigned char leds = ledstate; | ||
1367 | |||
1368 | tasklet_disable(&keyboard_tasklet); | 1389 | tasklet_disable(&keyboard_tasklet); |
1369 | if (leds != 0xff) { | 1390 | |
1370 | input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | 1391 | if (ledstate != 0xff) |
1371 | input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); | 1392 | kbd_update_leds_helper(handle, &ledstate); |
1372 | input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); | 1393 | |
1373 | input_inject_event(handle, EV_SYN, SYN_REPORT, 0); | ||
1374 | } | ||
1375 | tasklet_enable(&keyboard_tasklet); | 1394 | tasklet_enable(&keyboard_tasklet); |
1376 | } | 1395 | } |
1377 | 1396 | ||
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index e444c2dba160..938a3a273886 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -127,6 +127,7 @@ | |||
127 | #include <linux/wait.h> | 127 | #include <linux/wait.h> |
128 | #include <linux/jiffies.h> | 128 | #include <linux/jiffies.h> |
129 | #include <linux/smp_lock.h> | 129 | #include <linux/smp_lock.h> |
130 | #include <linux/compat.h> | ||
130 | 131 | ||
131 | #include <linux/parport.h> | 132 | #include <linux/parport.h> |
132 | #undef LP_STATS | 133 | #undef LP_STATS |
@@ -571,13 +572,11 @@ static int lp_release(struct inode * inode, struct file * file) | |||
571 | return 0; | 572 | return 0; |
572 | } | 573 | } |
573 | 574 | ||
574 | static int lp_ioctl(struct inode *inode, struct file *file, | 575 | static int lp_do_ioctl(unsigned int minor, unsigned int cmd, |
575 | unsigned int cmd, unsigned long arg) | 576 | unsigned long arg, void __user *argp) |
576 | { | 577 | { |
577 | unsigned int minor = iminor(inode); | ||
578 | int status; | 578 | int status; |
579 | int retval = 0; | 579 | int retval = 0; |
580 | void __user *argp = (void __user *)arg; | ||
581 | 580 | ||
582 | #ifdef LP_DEBUG | 581 | #ifdef LP_DEBUG |
583 | printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); | 582 | printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); |
@@ -587,9 +586,6 @@ static int lp_ioctl(struct inode *inode, struct file *file, | |||
587 | if ((LP_F(minor) & LP_EXIST) == 0) | 586 | if ((LP_F(minor) & LP_EXIST) == 0) |
588 | return -ENODEV; | 587 | return -ENODEV; |
589 | switch ( cmd ) { | 588 | switch ( cmd ) { |
590 | struct timeval par_timeout; | ||
591 | long to_jiffies; | ||
592 | |||
593 | case LPTIME: | 589 | case LPTIME: |
594 | LP_TIME(minor) = arg * HZ/100; | 590 | LP_TIME(minor) = arg * HZ/100; |
595 | break; | 591 | break; |
@@ -652,34 +648,101 @@ static int lp_ioctl(struct inode *inode, struct file *file, | |||
652 | return -EFAULT; | 648 | return -EFAULT; |
653 | break; | 649 | break; |
654 | 650 | ||
655 | case LPSETTIMEOUT: | ||
656 | if (copy_from_user (&par_timeout, argp, | ||
657 | sizeof (struct timeval))) { | ||
658 | return -EFAULT; | ||
659 | } | ||
660 | /* Convert to jiffies, place in lp_table */ | ||
661 | if ((par_timeout.tv_sec < 0) || | ||
662 | (par_timeout.tv_usec < 0)) { | ||
663 | return -EINVAL; | ||
664 | } | ||
665 | to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ); | ||
666 | to_jiffies += par_timeout.tv_sec * (long) HZ; | ||
667 | if (to_jiffies <= 0) { | ||
668 | return -EINVAL; | ||
669 | } | ||
670 | lp_table[minor].timeout = to_jiffies; | ||
671 | break; | ||
672 | |||
673 | default: | 651 | default: |
674 | retval = -EINVAL; | 652 | retval = -EINVAL; |
675 | } | 653 | } |
676 | return retval; | 654 | return retval; |
677 | } | 655 | } |
678 | 656 | ||
657 | static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout) | ||
658 | { | ||
659 | long to_jiffies; | ||
660 | |||
661 | /* Convert to jiffies, place in lp_table */ | ||
662 | if ((par_timeout->tv_sec < 0) || | ||
663 | (par_timeout->tv_usec < 0)) { | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | to_jiffies = DIV_ROUND_UP(par_timeout->tv_usec, 1000000/HZ); | ||
667 | to_jiffies += par_timeout->tv_sec * (long) HZ; | ||
668 | if (to_jiffies <= 0) { | ||
669 | return -EINVAL; | ||
670 | } | ||
671 | lp_table[minor].timeout = to_jiffies; | ||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | static long lp_ioctl(struct file *file, unsigned int cmd, | ||
676 | unsigned long arg) | ||
677 | { | ||
678 | unsigned int minor; | ||
679 | struct timeval par_timeout; | ||
680 | int ret; | ||
681 | |||
682 | minor = iminor(file->f_path.dentry->d_inode); | ||
683 | lock_kernel(); | ||
684 | switch (cmd) { | ||
685 | case LPSETTIMEOUT: | ||
686 | if (copy_from_user(&par_timeout, (void __user *)arg, | ||
687 | sizeof (struct timeval))) { | ||
688 | ret = -EFAULT; | ||
689 | break; | ||
690 | } | ||
691 | ret = lp_set_timeout(minor, &par_timeout); | ||
692 | break; | ||
693 | default: | ||
694 | ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg); | ||
695 | break; | ||
696 | } | ||
697 | unlock_kernel(); | ||
698 | |||
699 | return ret; | ||
700 | } | ||
701 | |||
702 | #ifdef CONFIG_COMPAT | ||
703 | static long lp_compat_ioctl(struct file *file, unsigned int cmd, | ||
704 | unsigned long arg) | ||
705 | { | ||
706 | unsigned int minor; | ||
707 | struct timeval par_timeout; | ||
708 | struct compat_timeval __user *tc; | ||
709 | int ret; | ||
710 | |||
711 | minor = iminor(file->f_path.dentry->d_inode); | ||
712 | lock_kernel(); | ||
713 | switch (cmd) { | ||
714 | case LPSETTIMEOUT: | ||
715 | tc = compat_ptr(arg); | ||
716 | if (get_user(par_timeout.tv_sec, &tc->tv_sec) || | ||
717 | get_user(par_timeout.tv_usec, &tc->tv_usec)) { | ||
718 | ret = -EFAULT; | ||
719 | break; | ||
720 | } | ||
721 | ret = lp_set_timeout(minor, &par_timeout); | ||
722 | break; | ||
723 | #ifdef LP_STATS | ||
724 | case LPGETSTATS: | ||
725 | /* FIXME: add an implementation if you set LP_STATS */ | ||
726 | ret = -EINVAL; | ||
727 | break; | ||
728 | #endif | ||
729 | default: | ||
730 | ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg)); | ||
731 | break; | ||
732 | } | ||
733 | unlock_kernel(); | ||
734 | |||
735 | return ret; | ||
736 | } | ||
737 | #endif | ||
738 | |||
679 | static const struct file_operations lp_fops = { | 739 | static const struct file_operations lp_fops = { |
680 | .owner = THIS_MODULE, | 740 | .owner = THIS_MODULE, |
681 | .write = lp_write, | 741 | .write = lp_write, |
682 | .ioctl = lp_ioctl, | 742 | .unlocked_ioctl = lp_ioctl, |
743 | #ifdef CONFIG_COMPAT | ||
744 | .compat_ioctl = lp_compat_ioctl, | ||
745 | #endif | ||
683 | .open = lp_open, | 746 | .open = lp_open, |
684 | .release = lp_release, | 747 | .release = lp_release, |
685 | #ifdef CONFIG_PARPORT_1284 | 748 | #ifdef CONFIG_PARPORT_1284 |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index a074fceb67d3..be832b6f8279 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Added devfs support. | 6 | * Added devfs support. |
7 | * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu> | 7 | * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu> |
8 | * Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com> | 8 | * Shared /dev/zero mmapping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/bootmem.h> | 26 | #include <linux/bootmem.h> |
27 | #include <linux/splice.h> | 27 | #include <linux/splice.h> |
28 | #include <linux/pfn.h> | 28 | #include <linux/pfn.h> |
29 | #include <linux/smp_lock.h> | ||
30 | 29 | ||
31 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
32 | #include <asm/io.h> | 31 | #include <asm/io.h> |
@@ -35,6 +34,16 @@ | |||
35 | # include <linux/efi.h> | 34 | # include <linux/efi.h> |
36 | #endif | 35 | #endif |
37 | 36 | ||
37 | static inline unsigned long size_inside_page(unsigned long start, | ||
38 | unsigned long size) | ||
39 | { | ||
40 | unsigned long sz; | ||
41 | |||
42 | sz = PAGE_SIZE - (start & (PAGE_SIZE - 1)); | ||
43 | |||
44 | return min(sz, size); | ||
45 | } | ||
46 | |||
38 | /* | 47 | /* |
39 | * Architectures vary in how they handle caching for addresses | 48 | * Architectures vary in how they handle caching for addresses |
40 | * outside of main memory. | 49 | * outside of main memory. |
@@ -44,7 +53,7 @@ static inline int uncached_access(struct file *file, unsigned long addr) | |||
44 | { | 53 | { |
45 | #if defined(CONFIG_IA64) | 54 | #if defined(CONFIG_IA64) |
46 | /* | 55 | /* |
47 | * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases. | 56 | * On ia64, we ignore O_DSYNC because we cannot tolerate memory attribute aliases. |
48 | */ | 57 | */ |
49 | return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); | 58 | return !(efi_mem_attributes(addr) & EFI_MEMORY_WB); |
50 | #elif defined(CONFIG_MIPS) | 59 | #elif defined(CONFIG_MIPS) |
@@ -57,9 +66,9 @@ static inline int uncached_access(struct file *file, unsigned long addr) | |||
57 | #else | 66 | #else |
58 | /* | 67 | /* |
59 | * Accessing memory above the top the kernel knows about or through a file pointer | 68 | * Accessing memory above the top the kernel knows about or through a file pointer |
60 | * that was marked O_SYNC will be done non-cached. | 69 | * that was marked O_DSYNC will be done non-cached. |
61 | */ | 70 | */ |
62 | if (file->f_flags & O_SYNC) | 71 | if (file->f_flags & O_DSYNC) |
63 | return 1; | 72 | return 1; |
64 | return addr >= __pa(high_memory); | 73 | return addr >= __pa(high_memory); |
65 | #endif | 74 | #endif |
@@ -127,9 +136,7 @@ static ssize_t read_mem(struct file * file, char __user * buf, | |||
127 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED | 136 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED |
128 | /* we don't have page 0 mapped on sparc and m68k.. */ | 137 | /* we don't have page 0 mapped on sparc and m68k.. */ |
129 | if (p < PAGE_SIZE) { | 138 | if (p < PAGE_SIZE) { |
130 | sz = PAGE_SIZE - p; | 139 | sz = size_inside_page(p, count); |
131 | if (sz > count) | ||
132 | sz = count; | ||
133 | if (sz > 0) { | 140 | if (sz > 0) { |
134 | if (clear_user(buf, sz)) | 141 | if (clear_user(buf, sz)) |
135 | return -EFAULT; | 142 | return -EFAULT; |
@@ -142,15 +149,9 @@ static ssize_t read_mem(struct file * file, char __user * buf, | |||
142 | #endif | 149 | #endif |
143 | 150 | ||
144 | while (count > 0) { | 151 | while (count > 0) { |
145 | /* | 152 | unsigned long remaining; |
146 | * Handle first page in case it's not aligned | ||
147 | */ | ||
148 | if (-p & (PAGE_SIZE - 1)) | ||
149 | sz = -p & (PAGE_SIZE - 1); | ||
150 | else | ||
151 | sz = PAGE_SIZE; | ||
152 | 153 | ||
153 | sz = min_t(unsigned long, sz, count); | 154 | sz = size_inside_page(p, count); |
154 | 155 | ||
155 | if (!range_is_allowed(p >> PAGE_SHIFT, count)) | 156 | if (!range_is_allowed(p >> PAGE_SHIFT, count)) |
156 | return -EPERM; | 157 | return -EPERM; |
@@ -164,12 +165,10 @@ static ssize_t read_mem(struct file * file, char __user * buf, | |||
164 | if (!ptr) | 165 | if (!ptr) |
165 | return -EFAULT; | 166 | return -EFAULT; |
166 | 167 | ||
167 | if (copy_to_user(buf, ptr, sz)) { | 168 | remaining = copy_to_user(buf, ptr, sz); |
168 | unxlate_dev_mem_ptr(p, ptr); | ||
169 | return -EFAULT; | ||
170 | } | ||
171 | |||
172 | unxlate_dev_mem_ptr(p, ptr); | 169 | unxlate_dev_mem_ptr(p, ptr); |
170 | if (remaining) | ||
171 | return -EFAULT; | ||
173 | 172 | ||
174 | buf += sz; | 173 | buf += sz; |
175 | p += sz; | 174 | p += sz; |
@@ -197,9 +196,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf, | |||
197 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED | 196 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED |
198 | /* we don't have page 0 mapped on sparc and m68k.. */ | 197 | /* we don't have page 0 mapped on sparc and m68k.. */ |
199 | if (p < PAGE_SIZE) { | 198 | if (p < PAGE_SIZE) { |
200 | unsigned long sz = PAGE_SIZE - p; | 199 | sz = size_inside_page(p, count); |
201 | if (sz > count) | ||
202 | sz = count; | ||
203 | /* Hmm. Do something? */ | 200 | /* Hmm. Do something? */ |
204 | buf += sz; | 201 | buf += sz; |
205 | p += sz; | 202 | p += sz; |
@@ -209,15 +206,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf, | |||
209 | #endif | 206 | #endif |
210 | 207 | ||
211 | while (count > 0) { | 208 | while (count > 0) { |
212 | /* | 209 | sz = size_inside_page(p, count); |
213 | * Handle first page in case it's not aligned | ||
214 | */ | ||
215 | if (-p & (PAGE_SIZE - 1)) | ||
216 | sz = -p & (PAGE_SIZE - 1); | ||
217 | else | ||
218 | sz = PAGE_SIZE; | ||
219 | |||
220 | sz = min_t(unsigned long, sz, count); | ||
221 | 210 | ||
222 | if (!range_is_allowed(p >> PAGE_SHIFT, sz)) | 211 | if (!range_is_allowed(p >> PAGE_SHIFT, sz)) |
223 | return -EPERM; | 212 | return -EPERM; |
@@ -235,16 +224,14 @@ static ssize_t write_mem(struct file * file, const char __user * buf, | |||
235 | } | 224 | } |
236 | 225 | ||
237 | copied = copy_from_user(ptr, buf, sz); | 226 | copied = copy_from_user(ptr, buf, sz); |
227 | unxlate_dev_mem_ptr(p, ptr); | ||
238 | if (copied) { | 228 | if (copied) { |
239 | written += sz - copied; | 229 | written += sz - copied; |
240 | unxlate_dev_mem_ptr(p, ptr); | ||
241 | if (written) | 230 | if (written) |
242 | break; | 231 | break; |
243 | return -EFAULT; | 232 | return -EFAULT; |
244 | } | 233 | } |
245 | 234 | ||
246 | unxlate_dev_mem_ptr(p, ptr); | ||
247 | |||
248 | buf += sz; | 235 | buf += sz; |
249 | p += sz; | 236 | p += sz; |
250 | count -= sz; | 237 | count -= sz; |
@@ -418,27 +405,18 @@ static ssize_t read_kmem(struct file *file, char __user *buf, | |||
418 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED | 405 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED |
419 | /* we don't have page 0 mapped on sparc and m68k.. */ | 406 | /* we don't have page 0 mapped on sparc and m68k.. */ |
420 | if (p < PAGE_SIZE && low_count > 0) { | 407 | if (p < PAGE_SIZE && low_count > 0) { |
421 | size_t tmp = PAGE_SIZE - p; | 408 | sz = size_inside_page(p, low_count); |
422 | if (tmp > low_count) tmp = low_count; | 409 | if (clear_user(buf, sz)) |
423 | if (clear_user(buf, tmp)) | ||
424 | return -EFAULT; | 410 | return -EFAULT; |
425 | buf += tmp; | 411 | buf += sz; |
426 | p += tmp; | 412 | p += sz; |
427 | read += tmp; | 413 | read += sz; |
428 | low_count -= tmp; | 414 | low_count -= sz; |
429 | count -= tmp; | 415 | count -= sz; |
430 | } | 416 | } |
431 | #endif | 417 | #endif |
432 | while (low_count > 0) { | 418 | while (low_count > 0) { |
433 | /* | 419 | sz = size_inside_page(p, low_count); |
434 | * Handle first page in case it's not aligned | ||
435 | */ | ||
436 | if (-p & (PAGE_SIZE - 1)) | ||
437 | sz = -p & (PAGE_SIZE - 1); | ||
438 | else | ||
439 | sz = PAGE_SIZE; | ||
440 | |||
441 | sz = min_t(unsigned long, sz, low_count); | ||
442 | 420 | ||
443 | /* | 421 | /* |
444 | * On ia64 if a page has been mapped somewhere as | 422 | * On ia64 if a page has been mapped somewhere as |
@@ -462,21 +440,18 @@ static ssize_t read_kmem(struct file *file, char __user *buf, | |||
462 | if (!kbuf) | 440 | if (!kbuf) |
463 | return -ENOMEM; | 441 | return -ENOMEM; |
464 | while (count > 0) { | 442 | while (count > 0) { |
465 | int len = count; | 443 | sz = size_inside_page(p, count); |
466 | 444 | sz = vread(kbuf, (char *)p, sz); | |
467 | if (len > PAGE_SIZE) | 445 | if (!sz) |
468 | len = PAGE_SIZE; | ||
469 | len = vread(kbuf, (char *)p, len); | ||
470 | if (!len) | ||
471 | break; | 446 | break; |
472 | if (copy_to_user(buf, kbuf, len)) { | 447 | if (copy_to_user(buf, kbuf, sz)) { |
473 | free_page((unsigned long)kbuf); | 448 | free_page((unsigned long)kbuf); |
474 | return -EFAULT; | 449 | return -EFAULT; |
475 | } | 450 | } |
476 | count -= len; | 451 | count -= sz; |
477 | buf += len; | 452 | buf += sz; |
478 | read += len; | 453 | read += sz; |
479 | p += len; | 454 | p += sz; |
480 | } | 455 | } |
481 | free_page((unsigned long)kbuf); | 456 | free_page((unsigned long)kbuf); |
482 | } | 457 | } |
@@ -486,7 +461,7 @@ static ssize_t read_kmem(struct file *file, char __user *buf, | |||
486 | 461 | ||
487 | 462 | ||
488 | static inline ssize_t | 463 | static inline ssize_t |
489 | do_write_kmem(void *p, unsigned long realp, const char __user * buf, | 464 | do_write_kmem(unsigned long p, const char __user *buf, |
490 | size_t count, loff_t *ppos) | 465 | size_t count, loff_t *ppos) |
491 | { | 466 | { |
492 | ssize_t written, sz; | 467 | ssize_t written, sz; |
@@ -495,14 +470,11 @@ do_write_kmem(void *p, unsigned long realp, const char __user * buf, | |||
495 | written = 0; | 470 | written = 0; |
496 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED | 471 | #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED |
497 | /* we don't have page 0 mapped on sparc and m68k.. */ | 472 | /* we don't have page 0 mapped on sparc and m68k.. */ |
498 | if (realp < PAGE_SIZE) { | 473 | if (p < PAGE_SIZE) { |
499 | unsigned long sz = PAGE_SIZE - realp; | 474 | sz = size_inside_page(p, count); |
500 | if (sz > count) | ||
501 | sz = count; | ||
502 | /* Hmm. Do something? */ | 475 | /* Hmm. Do something? */ |
503 | buf += sz; | 476 | buf += sz; |
504 | p += sz; | 477 | p += sz; |
505 | realp += sz; | ||
506 | count -= sz; | 478 | count -= sz; |
507 | written += sz; | 479 | written += sz; |
508 | } | 480 | } |
@@ -510,22 +482,15 @@ do_write_kmem(void *p, unsigned long realp, const char __user * buf, | |||
510 | 482 | ||
511 | while (count > 0) { | 483 | while (count > 0) { |
512 | char *ptr; | 484 | char *ptr; |
513 | /* | ||
514 | * Handle first page in case it's not aligned | ||
515 | */ | ||
516 | if (-realp & (PAGE_SIZE - 1)) | ||
517 | sz = -realp & (PAGE_SIZE - 1); | ||
518 | else | ||
519 | sz = PAGE_SIZE; | ||
520 | 485 | ||
521 | sz = min_t(unsigned long, sz, count); | 486 | sz = size_inside_page(p, count); |
522 | 487 | ||
523 | /* | 488 | /* |
524 | * On ia64 if a page has been mapped somewhere as | 489 | * On ia64 if a page has been mapped somewhere as |
525 | * uncached, then it must also be accessed uncached | 490 | * uncached, then it must also be accessed uncached |
526 | * by the kernel or data corruption may occur | 491 | * by the kernel or data corruption may occur |
527 | */ | 492 | */ |
528 | ptr = xlate_dev_kmem_ptr(p); | 493 | ptr = xlate_dev_kmem_ptr((char *)p); |
529 | 494 | ||
530 | copied = copy_from_user(ptr, buf, sz); | 495 | copied = copy_from_user(ptr, buf, sz); |
531 | if (copied) { | 496 | if (copied) { |
@@ -536,7 +501,6 @@ do_write_kmem(void *p, unsigned long realp, const char __user * buf, | |||
536 | } | 501 | } |
537 | buf += sz; | 502 | buf += sz; |
538 | p += sz; | 503 | p += sz; |
539 | realp += sz; | ||
540 | count -= sz; | 504 | count -= sz; |
541 | written += sz; | 505 | written += sz; |
542 | } | 506 | } |
@@ -555,19 +519,14 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, | |||
555 | unsigned long p = *ppos; | 519 | unsigned long p = *ppos; |
556 | ssize_t wrote = 0; | 520 | ssize_t wrote = 0; |
557 | ssize_t virtr = 0; | 521 | ssize_t virtr = 0; |
558 | ssize_t written; | ||
559 | char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ | 522 | char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ |
560 | 523 | ||
561 | if (p < (unsigned long) high_memory) { | 524 | if (p < (unsigned long) high_memory) { |
562 | 525 | unsigned long to_write = min_t(unsigned long, count, | |
563 | wrote = count; | 526 | (unsigned long)high_memory - p); |
564 | if (count > (unsigned long) high_memory - p) | 527 | wrote = do_write_kmem(p, buf, to_write, ppos); |
565 | wrote = (unsigned long) high_memory - p; | 528 | if (wrote != to_write) |
566 | 529 | return wrote; | |
567 | written = do_write_kmem((void*)p, p, buf, wrote, ppos); | ||
568 | if (written != wrote) | ||
569 | return written; | ||
570 | wrote = written; | ||
571 | p += wrote; | 530 | p += wrote; |
572 | buf += wrote; | 531 | buf += wrote; |
573 | count -= wrote; | 532 | count -= wrote; |
@@ -578,24 +537,21 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, | |||
578 | if (!kbuf) | 537 | if (!kbuf) |
579 | return wrote ? wrote : -ENOMEM; | 538 | return wrote ? wrote : -ENOMEM; |
580 | while (count > 0) { | 539 | while (count > 0) { |
581 | int len = count; | 540 | unsigned long sz = size_inside_page(p, count); |
582 | 541 | unsigned long n; | |
583 | if (len > PAGE_SIZE) | 542 | |
584 | len = PAGE_SIZE; | 543 | n = copy_from_user(kbuf, buf, sz); |
585 | if (len) { | 544 | if (n) { |
586 | written = copy_from_user(kbuf, buf, len); | 545 | if (wrote + virtr) |
587 | if (written) { | 546 | break; |
588 | if (wrote + virtr) | 547 | free_page((unsigned long)kbuf); |
589 | break; | 548 | return -EFAULT; |
590 | free_page((unsigned long)kbuf); | ||
591 | return -EFAULT; | ||
592 | } | ||
593 | } | 549 | } |
594 | len = vwrite(kbuf, (char *)p, len); | 550 | sz = vwrite(kbuf, (char *)p, sz); |
595 | count -= len; | 551 | count -= sz; |
596 | buf += len; | 552 | buf += sz; |
597 | virtr += len; | 553 | virtr += sz; |
598 | p += len; | 554 | p += sz; |
599 | } | 555 | } |
600 | free_page((unsigned long)kbuf); | 556 | free_page((unsigned long)kbuf); |
601 | } | 557 | } |
@@ -892,29 +848,23 @@ static int memory_open(struct inode *inode, struct file *filp) | |||
892 | { | 848 | { |
893 | int minor; | 849 | int minor; |
894 | const struct memdev *dev; | 850 | const struct memdev *dev; |
895 | int ret = -ENXIO; | ||
896 | |||
897 | lock_kernel(); | ||
898 | 851 | ||
899 | minor = iminor(inode); | 852 | minor = iminor(inode); |
900 | if (minor >= ARRAY_SIZE(devlist)) | 853 | if (minor >= ARRAY_SIZE(devlist)) |
901 | goto out; | 854 | return -ENXIO; |
902 | 855 | ||
903 | dev = &devlist[minor]; | 856 | dev = &devlist[minor]; |
904 | if (!dev->fops) | 857 | if (!dev->fops) |
905 | goto out; | 858 | return -ENXIO; |
906 | 859 | ||
907 | filp->f_op = dev->fops; | 860 | filp->f_op = dev->fops; |
908 | if (dev->dev_info) | 861 | if (dev->dev_info) |
909 | filp->f_mapping->backing_dev_info = dev->dev_info; | 862 | filp->f_mapping->backing_dev_info = dev->dev_info; |
910 | 863 | ||
911 | if (dev->fops->open) | 864 | if (dev->fops->open) |
912 | ret = dev->fops->open(inode, filp); | 865 | return dev->fops->open(inode, filp); |
913 | else | 866 | |
914 | ret = 0; | 867 | return 0; |
915 | out: | ||
916 | unlock_kernel(); | ||
917 | return ret; | ||
918 | } | 868 | } |
919 | 869 | ||
920 | static const struct file_operations memory_fops = { | 870 | static const struct file_operations memory_fops = { |
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 07fa612a58d5..94a136e96c06 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/device.h> | 49 | #include <linux/device.h> |
50 | #include <linux/tty.h> | 50 | #include <linux/tty.h> |
51 | #include <linux/kmod.h> | 51 | #include <linux/kmod.h> |
52 | #include <linux/smp_lock.h> | ||
53 | 52 | ||
54 | /* | 53 | /* |
55 | * Head entry for the doubly linked miscdevice list | 54 | * Head entry for the doubly linked miscdevice list |
@@ -61,9 +60,7 @@ static DEFINE_MUTEX(misc_mtx); | |||
61 | * Assigned numbers, used for dynamic minors | 60 | * Assigned numbers, used for dynamic minors |
62 | */ | 61 | */ |
63 | #define DYNAMIC_MINORS 64 /* like dynamic majors */ | 62 | #define DYNAMIC_MINORS 64 /* like dynamic majors */ |
64 | static unsigned char misc_minors[DYNAMIC_MINORS / 8]; | 63 | static DECLARE_BITMAP(misc_minors, DYNAMIC_MINORS); |
65 | |||
66 | extern int pmu_device_init(void); | ||
67 | 64 | ||
68 | #ifdef CONFIG_PROC_FS | 65 | #ifdef CONFIG_PROC_FS |
69 | static void *misc_seq_start(struct seq_file *seq, loff_t *pos) | 66 | static void *misc_seq_start(struct seq_file *seq, loff_t *pos) |
@@ -118,8 +115,7 @@ static int misc_open(struct inode * inode, struct file * file) | |||
118 | struct miscdevice *c; | 115 | struct miscdevice *c; |
119 | int err = -ENODEV; | 116 | int err = -ENODEV; |
120 | const struct file_operations *old_fops, *new_fops = NULL; | 117 | const struct file_operations *old_fops, *new_fops = NULL; |
121 | 118 | ||
122 | lock_kernel(); | ||
123 | mutex_lock(&misc_mtx); | 119 | mutex_lock(&misc_mtx); |
124 | 120 | ||
125 | list_for_each_entry(c, &misc_list, list) { | 121 | list_for_each_entry(c, &misc_list, list) { |
@@ -157,7 +153,6 @@ static int misc_open(struct inode * inode, struct file * file) | |||
157 | fops_put(old_fops); | 153 | fops_put(old_fops); |
158 | fail: | 154 | fail: |
159 | mutex_unlock(&misc_mtx); | 155 | mutex_unlock(&misc_mtx); |
160 | unlock_kernel(); | ||
161 | return err; | 156 | return err; |
162 | } | 157 | } |
163 | 158 | ||
@@ -201,24 +196,23 @@ int misc_register(struct miscdevice * misc) | |||
201 | } | 196 | } |
202 | 197 | ||
203 | if (misc->minor == MISC_DYNAMIC_MINOR) { | 198 | if (misc->minor == MISC_DYNAMIC_MINOR) { |
204 | int i = DYNAMIC_MINORS; | 199 | int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); |
205 | while (--i >= 0) | 200 | if (i >= DYNAMIC_MINORS) { |
206 | if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) | ||
207 | break; | ||
208 | if (i<0) { | ||
209 | mutex_unlock(&misc_mtx); | 201 | mutex_unlock(&misc_mtx); |
210 | return -EBUSY; | 202 | return -EBUSY; |
211 | } | 203 | } |
212 | misc->minor = i; | 204 | misc->minor = DYNAMIC_MINORS - i - 1; |
205 | set_bit(i, misc_minors); | ||
213 | } | 206 | } |
214 | 207 | ||
215 | if (misc->minor < DYNAMIC_MINORS) | ||
216 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); | ||
217 | dev = MKDEV(MISC_MAJOR, misc->minor); | 208 | dev = MKDEV(MISC_MAJOR, misc->minor); |
218 | 209 | ||
219 | misc->this_device = device_create(misc_class, misc->parent, dev, | 210 | misc->this_device = device_create(misc_class, misc->parent, dev, |
220 | misc, "%s", misc->name); | 211 | misc, "%s", misc->name); |
221 | if (IS_ERR(misc->this_device)) { | 212 | if (IS_ERR(misc->this_device)) { |
213 | int i = DYNAMIC_MINORS - misc->minor - 1; | ||
214 | if (i < DYNAMIC_MINORS && i >= 0) | ||
215 | clear_bit(i, misc_minors); | ||
222 | err = PTR_ERR(misc->this_device); | 216 | err = PTR_ERR(misc->this_device); |
223 | goto out; | 217 | goto out; |
224 | } | 218 | } |
@@ -245,7 +239,7 @@ int misc_register(struct miscdevice * misc) | |||
245 | 239 | ||
246 | int misc_deregister(struct miscdevice *misc) | 240 | int misc_deregister(struct miscdevice *misc) |
247 | { | 241 | { |
248 | int i = misc->minor; | 242 | int i = DYNAMIC_MINORS - misc->minor - 1; |
249 | 243 | ||
250 | if (list_empty(&misc->list)) | 244 | if (list_empty(&misc->list)) |
251 | return -EINVAL; | 245 | return -EINVAL; |
@@ -253,9 +247,8 @@ int misc_deregister(struct miscdevice *misc) | |||
253 | mutex_lock(&misc_mtx); | 247 | mutex_lock(&misc_mtx); |
254 | list_del(&misc->list); | 248 | list_del(&misc->list); |
255 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); | 249 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); |
256 | if (i < DYNAMIC_MINORS && i>0) { | 250 | if (i < DYNAMIC_MINORS && i >= 0) |
257 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); | 251 | clear_bit(i, misc_minors); |
258 | } | ||
259 | mutex_unlock(&misc_mtx); | 252 | mutex_unlock(&misc_mtx); |
260 | return 0; | 253 | return 0; |
261 | } | 254 | } |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index dd0083bbb64a..63ee3bbc1ce4 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/tty.h> | 34 | #include <linux/tty.h> |
35 | #include <linux/tty_flip.h> | 35 | #include <linux/tty_flip.h> |
36 | #include <linux/major.h> | 36 | #include <linux/major.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/string.h> | 37 | #include <linux/string.h> |
39 | #include <linux/fcntl.h> | 38 | #include <linux/fcntl.h> |
40 | #include <linux/ptrace.h> | 39 | #include <linux/ptrace.h> |
@@ -139,7 +138,7 @@ struct moxa_port { | |||
139 | int cflag; | 138 | int cflag; |
140 | unsigned long statusflags; | 139 | unsigned long statusflags; |
141 | 140 | ||
142 | u8 DCDState; | 141 | u8 DCDState; /* Protected by the port lock */ |
143 | u8 lineCtrl; | 142 | u8 lineCtrl; |
144 | u8 lowChkFlag; | 143 | u8 lowChkFlag; |
145 | }; | 144 | }; |
@@ -151,10 +150,9 @@ struct mon_str { | |||
151 | }; | 150 | }; |
152 | 151 | ||
153 | /* statusflags */ | 152 | /* statusflags */ |
154 | #define TXSTOPPED 0x1 | 153 | #define TXSTOPPED 1 |
155 | #define LOWWAIT 0x2 | 154 | #define LOWWAIT 2 |
156 | #define EMPTYWAIT 0x4 | 155 | #define EMPTYWAIT 3 |
157 | #define THROTTLE 0x8 | ||
158 | 156 | ||
159 | #define SERIAL_DO_RESTART | 157 | #define SERIAL_DO_RESTART |
160 | 158 | ||
@@ -165,6 +163,7 @@ static struct mon_str moxaLog; | |||
165 | static unsigned int moxaFuncTout = HZ / 2; | 163 | static unsigned int moxaFuncTout = HZ / 2; |
166 | static unsigned int moxaLowWaterChk; | 164 | static unsigned int moxaLowWaterChk; |
167 | static DEFINE_MUTEX(moxa_openlock); | 165 | static DEFINE_MUTEX(moxa_openlock); |
166 | static DEFINE_SPINLOCK(moxa_lock); | ||
168 | /* Variables for insmod */ | 167 | /* Variables for insmod */ |
169 | #ifdef MODULE | 168 | #ifdef MODULE |
170 | static unsigned long baseaddr[MAX_BOARDS]; | 169 | static unsigned long baseaddr[MAX_BOARDS]; |
@@ -194,8 +193,6 @@ static int moxa_write(struct tty_struct *, const unsigned char *, int); | |||
194 | static int moxa_write_room(struct tty_struct *); | 193 | static int moxa_write_room(struct tty_struct *); |
195 | static void moxa_flush_buffer(struct tty_struct *); | 194 | static void moxa_flush_buffer(struct tty_struct *); |
196 | static int moxa_chars_in_buffer(struct tty_struct *); | 195 | static int moxa_chars_in_buffer(struct tty_struct *); |
197 | static void moxa_throttle(struct tty_struct *); | ||
198 | static void moxa_unthrottle(struct tty_struct *); | ||
199 | static void moxa_set_termios(struct tty_struct *, struct ktermios *); | 196 | static void moxa_set_termios(struct tty_struct *, struct ktermios *); |
200 | static void moxa_stop(struct tty_struct *); | 197 | static void moxa_stop(struct tty_struct *); |
201 | static void moxa_start(struct tty_struct *); | 198 | static void moxa_start(struct tty_struct *); |
@@ -205,9 +202,9 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | |||
205 | unsigned int set, unsigned int clear); | 202 | unsigned int set, unsigned int clear); |
206 | static void moxa_poll(unsigned long); | 203 | static void moxa_poll(unsigned long); |
207 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); | 204 | static void moxa_set_tty_param(struct tty_struct *, struct ktermios *); |
208 | static void moxa_setup_empty_event(struct tty_struct *); | 205 | static void moxa_shutdown(struct tty_port *); |
209 | static void moxa_shut_down(struct tty_struct *); | ||
210 | static int moxa_carrier_raised(struct tty_port *); | 206 | static int moxa_carrier_raised(struct tty_port *); |
207 | static void moxa_dtr_rts(struct tty_port *, int); | ||
211 | /* | 208 | /* |
212 | * moxa board interface functions: | 209 | * moxa board interface functions: |
213 | */ | 210 | */ |
@@ -234,6 +231,8 @@ static void MoxaSetFifo(struct moxa_port *port, int enable); | |||
234 | * I/O functions | 231 | * I/O functions |
235 | */ | 232 | */ |
236 | 233 | ||
234 | static DEFINE_SPINLOCK(moxafunc_lock); | ||
235 | |||
237 | static void moxa_wait_finish(void __iomem *ofsAddr) | 236 | static void moxa_wait_finish(void __iomem *ofsAddr) |
238 | { | 237 | { |
239 | unsigned long end = jiffies + moxaFuncTout; | 238 | unsigned long end = jiffies + moxaFuncTout; |
@@ -247,9 +246,25 @@ static void moxa_wait_finish(void __iomem *ofsAddr) | |||
247 | 246 | ||
248 | static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg) | 247 | static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg) |
249 | { | 248 | { |
249 | unsigned long flags; | ||
250 | spin_lock_irqsave(&moxafunc_lock, flags); | ||
250 | writew(arg, ofsAddr + FuncArg); | 251 | writew(arg, ofsAddr + FuncArg); |
251 | writew(cmd, ofsAddr + FuncCode); | 252 | writew(cmd, ofsAddr + FuncCode); |
252 | moxa_wait_finish(ofsAddr); | 253 | moxa_wait_finish(ofsAddr); |
254 | spin_unlock_irqrestore(&moxafunc_lock, flags); | ||
255 | } | ||
256 | |||
257 | static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg) | ||
258 | { | ||
259 | unsigned long flags; | ||
260 | u16 ret; | ||
261 | spin_lock_irqsave(&moxafunc_lock, flags); | ||
262 | writew(arg, ofsAddr + FuncArg); | ||
263 | writew(cmd, ofsAddr + FuncCode); | ||
264 | moxa_wait_finish(ofsAddr); | ||
265 | ret = readw(ofsAddr + FuncArg); | ||
266 | spin_unlock_irqrestore(&moxafunc_lock, flags); | ||
267 | return ret; | ||
253 | } | 268 | } |
254 | 269 | ||
255 | static void moxa_low_water_check(void __iomem *ofsAddr) | 270 | static void moxa_low_water_check(void __iomem *ofsAddr) |
@@ -299,22 +314,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
299 | struct moxa_port *p; | 314 | struct moxa_port *p; |
300 | unsigned int i, j; | 315 | unsigned int i, j; |
301 | 316 | ||
302 | mutex_lock(&moxa_openlock); | ||
303 | for (i = 0; i < MAX_BOARDS; i++) { | 317 | for (i = 0; i < MAX_BOARDS; i++) { |
304 | p = moxa_boards[i].ports; | 318 | p = moxa_boards[i].ports; |
305 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { | 319 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { |
306 | memset(&tmp, 0, sizeof(tmp)); | 320 | memset(&tmp, 0, sizeof(tmp)); |
321 | spin_lock_bh(&moxa_lock); | ||
307 | if (moxa_boards[i].ready) { | 322 | if (moxa_boards[i].ready) { |
308 | tmp.inq = MoxaPortRxQueue(p); | 323 | tmp.inq = MoxaPortRxQueue(p); |
309 | tmp.outq = MoxaPortTxQueue(p); | 324 | tmp.outq = MoxaPortTxQueue(p); |
310 | } | 325 | } |
311 | if (copy_to_user(argm, &tmp, sizeof(tmp))) { | 326 | spin_unlock_bh(&moxa_lock); |
312 | mutex_unlock(&moxa_openlock); | 327 | if (copy_to_user(argm, &tmp, sizeof(tmp))) |
313 | return -EFAULT; | 328 | return -EFAULT; |
314 | } | ||
315 | } | 329 | } |
316 | } | 330 | } |
317 | mutex_unlock(&moxa_openlock); | ||
318 | break; | 331 | break; |
319 | } case MOXA_GET_OQUEUE: | 332 | } case MOXA_GET_OQUEUE: |
320 | status = MoxaPortTxQueue(ch); | 333 | status = MoxaPortTxQueue(ch); |
@@ -330,16 +343,20 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
330 | struct moxa_port *p; | 343 | struct moxa_port *p; |
331 | unsigned int i, j; | 344 | unsigned int i, j; |
332 | 345 | ||
333 | mutex_lock(&moxa_openlock); | ||
334 | for (i = 0; i < MAX_BOARDS; i++) { | 346 | for (i = 0; i < MAX_BOARDS; i++) { |
335 | p = moxa_boards[i].ports; | 347 | p = moxa_boards[i].ports; |
336 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { | 348 | for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) { |
337 | struct tty_struct *ttyp; | 349 | struct tty_struct *ttyp; |
338 | memset(&tmp, 0, sizeof(tmp)); | 350 | memset(&tmp, 0, sizeof(tmp)); |
339 | if (!moxa_boards[i].ready) | 351 | spin_lock_bh(&moxa_lock); |
352 | if (!moxa_boards[i].ready) { | ||
353 | spin_unlock_bh(&moxa_lock); | ||
340 | goto copy; | 354 | goto copy; |
355 | } | ||
341 | 356 | ||
342 | status = MoxaPortLineStatus(p); | 357 | status = MoxaPortLineStatus(p); |
358 | spin_unlock_bh(&moxa_lock); | ||
359 | |||
343 | if (status & 1) | 360 | if (status & 1) |
344 | tmp.cts = 1; | 361 | tmp.cts = 1; |
345 | if (status & 2) | 362 | if (status & 2) |
@@ -354,24 +371,21 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
354 | tmp.cflag = ttyp->termios->c_cflag; | 371 | tmp.cflag = ttyp->termios->c_cflag; |
355 | tty_kref_put(tty); | 372 | tty_kref_put(tty); |
356 | copy: | 373 | copy: |
357 | if (copy_to_user(argm, &tmp, sizeof(tmp))) { | 374 | if (copy_to_user(argm, &tmp, sizeof(tmp))) |
358 | mutex_unlock(&moxa_openlock); | ||
359 | return -EFAULT; | 375 | return -EFAULT; |
360 | } | ||
361 | } | 376 | } |
362 | } | 377 | } |
363 | mutex_unlock(&moxa_openlock); | ||
364 | break; | 378 | break; |
365 | } | 379 | } |
366 | case TIOCGSERIAL: | 380 | case TIOCGSERIAL: |
367 | mutex_lock(&moxa_openlock); | 381 | mutex_lock(&ch->port.mutex); |
368 | ret = moxa_get_serial_info(ch, argp); | 382 | ret = moxa_get_serial_info(ch, argp); |
369 | mutex_unlock(&moxa_openlock); | 383 | mutex_unlock(&ch->port.mutex); |
370 | break; | 384 | break; |
371 | case TIOCSSERIAL: | 385 | case TIOCSSERIAL: |
372 | mutex_lock(&moxa_openlock); | 386 | mutex_lock(&ch->port.mutex); |
373 | ret = moxa_set_serial_info(ch, argp); | 387 | ret = moxa_set_serial_info(ch, argp); |
374 | mutex_unlock(&moxa_openlock); | 388 | mutex_unlock(&ch->port.mutex); |
375 | break; | 389 | break; |
376 | default: | 390 | default: |
377 | ret = -ENOIOCTLCMD; | 391 | ret = -ENOIOCTLCMD; |
@@ -396,8 +410,6 @@ static const struct tty_operations moxa_ops = { | |||
396 | .flush_buffer = moxa_flush_buffer, | 410 | .flush_buffer = moxa_flush_buffer, |
397 | .chars_in_buffer = moxa_chars_in_buffer, | 411 | .chars_in_buffer = moxa_chars_in_buffer, |
398 | .ioctl = moxa_ioctl, | 412 | .ioctl = moxa_ioctl, |
399 | .throttle = moxa_throttle, | ||
400 | .unthrottle = moxa_unthrottle, | ||
401 | .set_termios = moxa_set_termios, | 413 | .set_termios = moxa_set_termios, |
402 | .stop = moxa_stop, | 414 | .stop = moxa_stop, |
403 | .start = moxa_start, | 415 | .start = moxa_start, |
@@ -409,11 +421,12 @@ static const struct tty_operations moxa_ops = { | |||
409 | 421 | ||
410 | static const struct tty_port_operations moxa_port_ops = { | 422 | static const struct tty_port_operations moxa_port_ops = { |
411 | .carrier_raised = moxa_carrier_raised, | 423 | .carrier_raised = moxa_carrier_raised, |
424 | .dtr_rts = moxa_dtr_rts, | ||
425 | .shutdown = moxa_shutdown, | ||
412 | }; | 426 | }; |
413 | 427 | ||
414 | static struct tty_driver *moxaDriver; | 428 | static struct tty_driver *moxaDriver; |
415 | static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); | 429 | static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0); |
416 | static DEFINE_SPINLOCK(moxa_lock); | ||
417 | 430 | ||
418 | /* | 431 | /* |
419 | * HW init | 432 | * HW init |
@@ -1112,14 +1125,12 @@ static void __exit moxa_exit(void) | |||
1112 | module_init(moxa_init); | 1125 | module_init(moxa_init); |
1113 | module_exit(moxa_exit); | 1126 | module_exit(moxa_exit); |
1114 | 1127 | ||
1115 | static void moxa_close_port(struct tty_struct *tty) | 1128 | static void moxa_shutdown(struct tty_port *port) |
1116 | { | 1129 | { |
1117 | struct moxa_port *ch = tty->driver_data; | 1130 | struct moxa_port *ch = container_of(port, struct moxa_port, port); |
1118 | moxa_shut_down(tty); | 1131 | MoxaPortDisable(ch); |
1119 | MoxaPortFlushData(ch, 2); | 1132 | MoxaPortFlushData(ch, 2); |
1120 | ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 1133 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); |
1121 | tty->driver_data = NULL; | ||
1122 | tty_port_tty_set(&ch->port, NULL); | ||
1123 | } | 1134 | } |
1124 | 1135 | ||
1125 | static int moxa_carrier_raised(struct tty_port *port) | 1136 | static int moxa_carrier_raised(struct tty_port *port) |
@@ -1127,45 +1138,19 @@ static int moxa_carrier_raised(struct tty_port *port) | |||
1127 | struct moxa_port *ch = container_of(port, struct moxa_port, port); | 1138 | struct moxa_port *ch = container_of(port, struct moxa_port, port); |
1128 | int dcd; | 1139 | int dcd; |
1129 | 1140 | ||
1130 | spin_lock_bh(&moxa_lock); | 1141 | spin_lock_irq(&port->lock); |
1131 | dcd = ch->DCDState; | 1142 | dcd = ch->DCDState; |
1132 | spin_unlock_bh(&moxa_lock); | 1143 | spin_unlock_irq(&port->lock); |
1133 | return dcd; | 1144 | return dcd; |
1134 | } | 1145 | } |
1135 | 1146 | ||
1136 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, | 1147 | static void moxa_dtr_rts(struct tty_port *port, int onoff) |
1137 | struct moxa_port *ch) | ||
1138 | { | 1148 | { |
1139 | struct tty_port *port = &ch->port; | 1149 | struct moxa_port *ch = container_of(port, struct moxa_port, port); |
1140 | DEFINE_WAIT(wait); | 1150 | MoxaPortLineCtrl(ch, onoff, onoff); |
1141 | int retval = 0; | ||
1142 | u8 dcd; | ||
1143 | |||
1144 | while (1) { | ||
1145 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); | ||
1146 | if (tty_hung_up_p(filp)) { | ||
1147 | #ifdef SERIAL_DO_RESTART | ||
1148 | retval = -ERESTARTSYS; | ||
1149 | #else | ||
1150 | retval = -EAGAIN; | ||
1151 | #endif | ||
1152 | break; | ||
1153 | } | ||
1154 | dcd = tty_port_carrier_raised(port); | ||
1155 | if (dcd) | ||
1156 | break; | ||
1157 | |||
1158 | if (signal_pending(current)) { | ||
1159 | retval = -ERESTARTSYS; | ||
1160 | break; | ||
1161 | } | ||
1162 | schedule(); | ||
1163 | } | ||
1164 | finish_wait(&port->open_wait, &wait); | ||
1165 | |||
1166 | return retval; | ||
1167 | } | 1151 | } |
1168 | 1152 | ||
1153 | |||
1169 | static int moxa_open(struct tty_struct *tty, struct file *filp) | 1154 | static int moxa_open(struct tty_struct *tty, struct file *filp) |
1170 | { | 1155 | { |
1171 | struct moxa_board_conf *brd; | 1156 | struct moxa_board_conf *brd; |
@@ -1194,6 +1179,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1194 | ch->port.count++; | 1179 | ch->port.count++; |
1195 | tty->driver_data = ch; | 1180 | tty->driver_data = ch; |
1196 | tty_port_tty_set(&ch->port, tty); | 1181 | tty_port_tty_set(&ch->port, tty); |
1182 | mutex_lock(&ch->port.mutex); | ||
1197 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { | 1183 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { |
1198 | ch->statusflags = 0; | 1184 | ch->statusflags = 0; |
1199 | moxa_set_tty_param(tty, tty->termios); | 1185 | moxa_set_tty_param(tty, tty->termios); |
@@ -1202,58 +1188,20 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1202 | MoxaSetFifo(ch, ch->type == PORT_16550A); | 1188 | MoxaSetFifo(ch, ch->type == PORT_16550A); |
1203 | ch->port.flags |= ASYNC_INITIALIZED; | 1189 | ch->port.flags |= ASYNC_INITIALIZED; |
1204 | } | 1190 | } |
1191 | mutex_unlock(&ch->port.mutex); | ||
1205 | mutex_unlock(&moxa_openlock); | 1192 | mutex_unlock(&moxa_openlock); |
1206 | 1193 | ||
1207 | retval = 0; | 1194 | retval = tty_port_block_til_ready(&ch->port, tty, filp); |
1208 | if (!(filp->f_flags & O_NONBLOCK) && !C_CLOCAL(tty)) | 1195 | if (retval == 0) |
1209 | retval = moxa_block_till_ready(tty, filp, ch); | 1196 | set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags); |
1210 | mutex_lock(&moxa_openlock); | ||
1211 | if (retval) { | ||
1212 | if (ch->port.count) /* 0 means already hung up... */ | ||
1213 | if (--ch->port.count == 0) | ||
1214 | moxa_close_port(tty); | ||
1215 | } else | ||
1216 | ch->port.flags |= ASYNC_NORMAL_ACTIVE; | ||
1217 | mutex_unlock(&moxa_openlock); | ||
1218 | |||
1219 | return retval; | 1197 | return retval; |
1220 | } | 1198 | } |
1221 | 1199 | ||
1222 | static void moxa_close(struct tty_struct *tty, struct file *filp) | 1200 | static void moxa_close(struct tty_struct *tty, struct file *filp) |
1223 | { | 1201 | { |
1224 | struct moxa_port *ch; | 1202 | struct moxa_port *ch = tty->driver_data; |
1225 | int port; | ||
1226 | |||
1227 | port = tty->index; | ||
1228 | if (port == MAX_PORTS || tty_hung_up_p(filp)) | ||
1229 | return; | ||
1230 | |||
1231 | mutex_lock(&moxa_openlock); | ||
1232 | ch = tty->driver_data; | ||
1233 | if (ch == NULL) | ||
1234 | goto unlock; | ||
1235 | if (tty->count == 1 && ch->port.count != 1) { | ||
1236 | printk(KERN_WARNING "moxa_close: bad serial port count; " | ||
1237 | "tty->count is 1, ch->port.count is %d\n", ch->port.count); | ||
1238 | ch->port.count = 1; | ||
1239 | } | ||
1240 | if (--ch->port.count < 0) { | ||
1241 | printk(KERN_WARNING "moxa_close: bad serial port count, " | ||
1242 | "device=%s\n", tty->name); | ||
1243 | ch->port.count = 0; | ||
1244 | } | ||
1245 | if (ch->port.count) | ||
1246 | goto unlock; | ||
1247 | |||
1248 | ch->cflag = tty->termios->c_cflag; | 1203 | ch->cflag = tty->termios->c_cflag; |
1249 | if (ch->port.flags & ASYNC_INITIALIZED) { | 1204 | tty_port_close(&ch->port, tty, filp); |
1250 | moxa_setup_empty_event(tty); | ||
1251 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ | ||
1252 | } | ||
1253 | |||
1254 | moxa_close_port(tty); | ||
1255 | unlock: | ||
1256 | mutex_unlock(&moxa_openlock); | ||
1257 | } | 1205 | } |
1258 | 1206 | ||
1259 | static int moxa_write(struct tty_struct *tty, | 1207 | static int moxa_write(struct tty_struct *tty, |
@@ -1269,7 +1217,7 @@ static int moxa_write(struct tty_struct *tty, | |||
1269 | len = MoxaPortWriteData(tty, buf, count); | 1217 | len = MoxaPortWriteData(tty, buf, count); |
1270 | spin_unlock_bh(&moxa_lock); | 1218 | spin_unlock_bh(&moxa_lock); |
1271 | 1219 | ||
1272 | ch->statusflags |= LOWWAIT; | 1220 | set_bit(LOWWAIT, &ch->statusflags); |
1273 | return len; | 1221 | return len; |
1274 | } | 1222 | } |
1275 | 1223 | ||
@@ -1300,40 +1248,21 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) | |||
1300 | struct moxa_port *ch = tty->driver_data; | 1248 | struct moxa_port *ch = tty->driver_data; |
1301 | int chars; | 1249 | int chars; |
1302 | 1250 | ||
1303 | /* | ||
1304 | * Sigh...I have to check if driver_data is NULL here, because | ||
1305 | * if an open() fails, the TTY subsystem eventually calls | ||
1306 | * tty_wait_until_sent(), which calls the driver's chars_in_buffer() | ||
1307 | * routine. And since the open() failed, we return 0 here. TDJ | ||
1308 | */ | ||
1309 | if (ch == NULL) | ||
1310 | return 0; | ||
1311 | lock_kernel(); | ||
1312 | chars = MoxaPortTxQueue(ch); | 1251 | chars = MoxaPortTxQueue(ch); |
1313 | if (chars) { | 1252 | if (chars) |
1314 | /* | 1253 | /* |
1315 | * Make it possible to wakeup anything waiting for output | 1254 | * Make it possible to wakeup anything waiting for output |
1316 | * in tty_ioctl.c, etc. | 1255 | * in tty_ioctl.c, etc. |
1317 | */ | 1256 | */ |
1318 | if (!(ch->statusflags & EMPTYWAIT)) | 1257 | set_bit(EMPTYWAIT, &ch->statusflags); |
1319 | moxa_setup_empty_event(tty); | ||
1320 | } | ||
1321 | unlock_kernel(); | ||
1322 | return chars; | 1258 | return chars; |
1323 | } | 1259 | } |
1324 | 1260 | ||
1325 | static int moxa_tiocmget(struct tty_struct *tty, struct file *file) | 1261 | static int moxa_tiocmget(struct tty_struct *tty, struct file *file) |
1326 | { | 1262 | { |
1327 | struct moxa_port *ch; | 1263 | struct moxa_port *ch = tty->driver_data; |
1328 | int flag = 0, dtr, rts; | 1264 | int flag = 0, dtr, rts; |
1329 | 1265 | ||
1330 | mutex_lock(&moxa_openlock); | ||
1331 | ch = tty->driver_data; | ||
1332 | if (!ch) { | ||
1333 | mutex_unlock(&moxa_openlock); | ||
1334 | return -EINVAL; | ||
1335 | } | ||
1336 | |||
1337 | MoxaPortGetLineOut(ch, &dtr, &rts); | 1266 | MoxaPortGetLineOut(ch, &dtr, &rts); |
1338 | if (dtr) | 1267 | if (dtr) |
1339 | flag |= TIOCM_DTR; | 1268 | flag |= TIOCM_DTR; |
@@ -1346,7 +1275,6 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file) | |||
1346 | flag |= TIOCM_DSR; | 1275 | flag |= TIOCM_DSR; |
1347 | if (dtr & 4) | 1276 | if (dtr & 4) |
1348 | flag |= TIOCM_CD; | 1277 | flag |= TIOCM_CD; |
1349 | mutex_unlock(&moxa_openlock); | ||
1350 | return flag; | 1278 | return flag; |
1351 | } | 1279 | } |
1352 | 1280 | ||
@@ -1379,20 +1307,6 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | |||
1379 | return 0; | 1307 | return 0; |
1380 | } | 1308 | } |
1381 | 1309 | ||
1382 | static void moxa_throttle(struct tty_struct *tty) | ||
1383 | { | ||
1384 | struct moxa_port *ch = tty->driver_data; | ||
1385 | |||
1386 | ch->statusflags |= THROTTLE; | ||
1387 | } | ||
1388 | |||
1389 | static void moxa_unthrottle(struct tty_struct *tty) | ||
1390 | { | ||
1391 | struct moxa_port *ch = tty->driver_data; | ||
1392 | |||
1393 | ch->statusflags &= ~THROTTLE; | ||
1394 | } | ||
1395 | |||
1396 | static void moxa_set_termios(struct tty_struct *tty, | 1310 | static void moxa_set_termios(struct tty_struct *tty, |
1397 | struct ktermios *old_termios) | 1311 | struct ktermios *old_termios) |
1398 | { | 1312 | { |
@@ -1412,7 +1326,7 @@ static void moxa_stop(struct tty_struct *tty) | |||
1412 | if (ch == NULL) | 1326 | if (ch == NULL) |
1413 | return; | 1327 | return; |
1414 | MoxaPortTxDisable(ch); | 1328 | MoxaPortTxDisable(ch); |
1415 | ch->statusflags |= TXSTOPPED; | 1329 | set_bit(TXSTOPPED, &ch->statusflags); |
1416 | } | 1330 | } |
1417 | 1331 | ||
1418 | 1332 | ||
@@ -1427,38 +1341,32 @@ static void moxa_start(struct tty_struct *tty) | |||
1427 | return; | 1341 | return; |
1428 | 1342 | ||
1429 | MoxaPortTxEnable(ch); | 1343 | MoxaPortTxEnable(ch); |
1430 | ch->statusflags &= ~TXSTOPPED; | 1344 | clear_bit(TXSTOPPED, &ch->statusflags); |
1431 | } | 1345 | } |
1432 | 1346 | ||
1433 | static void moxa_hangup(struct tty_struct *tty) | 1347 | static void moxa_hangup(struct tty_struct *tty) |
1434 | { | 1348 | { |
1435 | struct moxa_port *ch; | 1349 | struct moxa_port *ch = tty->driver_data; |
1436 | 1350 | tty_port_hangup(&ch->port); | |
1437 | mutex_lock(&moxa_openlock); | ||
1438 | ch = tty->driver_data; | ||
1439 | if (ch == NULL) { | ||
1440 | mutex_unlock(&moxa_openlock); | ||
1441 | return; | ||
1442 | } | ||
1443 | ch->port.count = 0; | ||
1444 | moxa_close_port(tty); | ||
1445 | mutex_unlock(&moxa_openlock); | ||
1446 | |||
1447 | wake_up_interruptible(&ch->port.open_wait); | ||
1448 | } | 1351 | } |
1449 | 1352 | ||
1450 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) | 1353 | static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) |
1451 | { | 1354 | { |
1452 | struct tty_struct *tty; | 1355 | struct tty_struct *tty; |
1356 | unsigned long flags; | ||
1453 | dcd = !!dcd; | 1357 | dcd = !!dcd; |
1454 | 1358 | ||
1359 | spin_lock_irqsave(&p->port.lock, flags); | ||
1455 | if (dcd != p->DCDState) { | 1360 | if (dcd != p->DCDState) { |
1361 | p->DCDState = dcd; | ||
1362 | spin_unlock_irqrestore(&p->port.lock, flags); | ||
1456 | tty = tty_port_tty_get(&p->port); | 1363 | tty = tty_port_tty_get(&p->port); |
1457 | if (tty && C_CLOCAL(tty) && !dcd) | 1364 | if (tty && C_CLOCAL(tty) && !dcd) |
1458 | tty_hangup(tty); | 1365 | tty_hangup(tty); |
1459 | tty_kref_put(tty); | 1366 | tty_kref_put(tty); |
1460 | } | 1367 | } |
1461 | p->DCDState = dcd; | 1368 | else |
1369 | spin_unlock_irqrestore(&p->port.lock, flags); | ||
1462 | } | 1370 | } |
1463 | 1371 | ||
1464 | static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | 1372 | static int moxa_poll_port(struct moxa_port *p, unsigned int handle, |
@@ -1470,24 +1378,24 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1470 | u16 intr; | 1378 | u16 intr; |
1471 | 1379 | ||
1472 | if (tty) { | 1380 | if (tty) { |
1473 | if ((p->statusflags & EMPTYWAIT) && | 1381 | if (test_bit(EMPTYWAIT, &p->statusflags) && |
1474 | MoxaPortTxQueue(p) == 0) { | 1382 | MoxaPortTxQueue(p) == 0) { |
1475 | p->statusflags &= ~EMPTYWAIT; | 1383 | clear_bit(EMPTYWAIT, &p->statusflags); |
1476 | tty_wakeup(tty); | 1384 | tty_wakeup(tty); |
1477 | } | 1385 | } |
1478 | if ((p->statusflags & LOWWAIT) && !tty->stopped && | 1386 | if (test_bit(LOWWAIT, &p->statusflags) && !tty->stopped && |
1479 | MoxaPortTxQueue(p) <= WAKEUP_CHARS) { | 1387 | MoxaPortTxQueue(p) <= WAKEUP_CHARS) { |
1480 | p->statusflags &= ~LOWWAIT; | 1388 | clear_bit(LOWWAIT, &p->statusflags); |
1481 | tty_wakeup(tty); | 1389 | tty_wakeup(tty); |
1482 | } | 1390 | } |
1483 | 1391 | ||
1484 | if (inited && !(p->statusflags & THROTTLE) && | 1392 | if (inited && !test_bit(TTY_THROTTLED, &tty->flags) && |
1485 | MoxaPortRxQueue(p) > 0) { /* RX */ | 1393 | MoxaPortRxQueue(p) > 0) { /* RX */ |
1486 | MoxaPortReadData(p); | 1394 | MoxaPortReadData(p); |
1487 | tty_schedule_flip(tty); | 1395 | tty_schedule_flip(tty); |
1488 | } | 1396 | } |
1489 | } else { | 1397 | } else { |
1490 | p->statusflags &= ~EMPTYWAIT; | 1398 | clear_bit(EMPTYWAIT, &p->statusflags); |
1491 | MoxaPortFlushData(p, 0); /* flush RX */ | 1399 | MoxaPortFlushData(p, 0); /* flush RX */ |
1492 | } | 1400 | } |
1493 | 1401 | ||
@@ -1588,35 +1496,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term | |||
1588 | tty_encode_baud_rate(tty, baud, baud); | 1496 | tty_encode_baud_rate(tty, baud, baud); |
1589 | } | 1497 | } |
1590 | 1498 | ||
1591 | static void moxa_setup_empty_event(struct tty_struct *tty) | ||
1592 | { | ||
1593 | struct moxa_port *ch = tty->driver_data; | ||
1594 | |||
1595 | spin_lock_bh(&moxa_lock); | ||
1596 | ch->statusflags |= EMPTYWAIT; | ||
1597 | spin_unlock_bh(&moxa_lock); | ||
1598 | } | ||
1599 | |||
1600 | static void moxa_shut_down(struct tty_struct *tty) | ||
1601 | { | ||
1602 | struct moxa_port *ch = tty->driver_data; | ||
1603 | |||
1604 | if (!(ch->port.flags & ASYNC_INITIALIZED)) | ||
1605 | return; | ||
1606 | |||
1607 | MoxaPortDisable(ch); | ||
1608 | |||
1609 | /* | ||
1610 | * If we're a modem control device and HUPCL is on, drop RTS & DTR. | ||
1611 | */ | ||
1612 | if (C_HUPCL(tty)) | ||
1613 | MoxaPortLineCtrl(ch, 0, 0); | ||
1614 | |||
1615 | spin_lock_bh(&moxa_lock); | ||
1616 | ch->port.flags &= ~ASYNC_INITIALIZED; | ||
1617 | spin_unlock_bh(&moxa_lock); | ||
1618 | } | ||
1619 | |||
1620 | /***************************************************************************** | 1499 | /***************************************************************************** |
1621 | * Driver level functions: * | 1500 | * Driver level functions: * |
1622 | *****************************************************************************/ | 1501 | *****************************************************************************/ |
@@ -1918,10 +1797,12 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio, | |||
1918 | baud = MoxaPortSetBaud(port, baud); | 1797 | baud = MoxaPortSetBaud(port, baud); |
1919 | 1798 | ||
1920 | if (termio->c_iflag & (IXON | IXOFF | IXANY)) { | 1799 | if (termio->c_iflag & (IXON | IXOFF | IXANY)) { |
1800 | spin_lock_irq(&moxafunc_lock); | ||
1921 | writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); | 1801 | writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); |
1922 | writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); | 1802 | writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); |
1923 | writeb(FC_SetXonXoff, ofsAddr + FuncCode); | 1803 | writeb(FC_SetXonXoff, ofsAddr + FuncCode); |
1924 | moxa_wait_finish(ofsAddr); | 1804 | moxa_wait_finish(ofsAddr); |
1805 | spin_unlock_irq(&moxafunc_lock); | ||
1925 | 1806 | ||
1926 | } | 1807 | } |
1927 | return baud; | 1808 | return baud; |
@@ -1974,18 +1855,14 @@ static int MoxaPortLineStatus(struct moxa_port *port) | |||
1974 | int val; | 1855 | int val; |
1975 | 1856 | ||
1976 | ofsAddr = port->tableAddr; | 1857 | ofsAddr = port->tableAddr; |
1977 | if (MOXA_IS_320(port->board)) { | 1858 | if (MOXA_IS_320(port->board)) |
1978 | moxafunc(ofsAddr, FC_LineStatus, 0); | 1859 | val = moxafuncret(ofsAddr, FC_LineStatus, 0); |
1979 | val = readw(ofsAddr + FuncArg); | 1860 | else |
1980 | } else { | ||
1981 | val = readw(ofsAddr + FlagStat) >> 4; | 1861 | val = readw(ofsAddr + FlagStat) >> 4; |
1982 | } | ||
1983 | val &= 0x0B; | 1862 | val &= 0x0B; |
1984 | if (val & 8) | 1863 | if (val & 8) |
1985 | val |= 4; | 1864 | val |= 4; |
1986 | spin_lock_bh(&moxa_lock); | ||
1987 | moxa_new_dcdstate(port, val & 8); | 1865 | moxa_new_dcdstate(port, val & 8); |
1988 | spin_unlock_bh(&moxa_lock); | ||
1989 | val &= 7; | 1866 | val &= 7; |
1990 | return val; | 1867 | return val; |
1991 | } | 1868 | } |
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index 1997270bb6f4..ecb89d798e35 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c | |||
@@ -248,7 +248,7 @@ static const struct vm_operations_struct mspec_vm_ops = { | |||
248 | /* | 248 | /* |
249 | * mspec_mmap | 249 | * mspec_mmap |
250 | * | 250 | * |
251 | * Called when mmaping the device. Initializes the vma with a fault handler | 251 | * Called when mmapping the device. Initializes the vma with a fault handler |
252 | * and private data structure necessary to allocate, track, and free the | 252 | * and private data structure necessary to allocate, track, and free the |
253 | * underlying pages. | 253 | * underlying pages. |
254 | */ | 254 | */ |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 5e28d39b9e81..3d923065d9a2 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/signal.h> | 24 | #include <linux/signal.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/timer.h> | 26 | #include <linux/timer.h> |
28 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
29 | #include <linux/tty.h> | 28 | #include <linux/tty.h> |
@@ -856,9 +855,9 @@ static void mxser_check_modem_status(struct tty_struct *tty, | |||
856 | } | 855 | } |
857 | } | 856 | } |
858 | 857 | ||
859 | static int mxser_startup(struct tty_struct *tty) | 858 | static int mxser_activate(struct tty_port *port, struct tty_struct *tty) |
860 | { | 859 | { |
861 | struct mxser_port *info = tty->driver_data; | 860 | struct mxser_port *info = container_of(port, struct mxser_port, port); |
862 | unsigned long page; | 861 | unsigned long page; |
863 | unsigned long flags; | 862 | unsigned long flags; |
864 | 863 | ||
@@ -868,22 +867,13 @@ static int mxser_startup(struct tty_struct *tty) | |||
868 | 867 | ||
869 | spin_lock_irqsave(&info->slock, flags); | 868 | spin_lock_irqsave(&info->slock, flags); |
870 | 869 | ||
871 | if (info->port.flags & ASYNC_INITIALIZED) { | ||
872 | free_page(page); | ||
873 | spin_unlock_irqrestore(&info->slock, flags); | ||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | if (!info->ioaddr || !info->type) { | 870 | if (!info->ioaddr || !info->type) { |
878 | set_bit(TTY_IO_ERROR, &tty->flags); | 871 | set_bit(TTY_IO_ERROR, &tty->flags); |
879 | free_page(page); | 872 | free_page(page); |
880 | spin_unlock_irqrestore(&info->slock, flags); | 873 | spin_unlock_irqrestore(&info->slock, flags); |
881 | return 0; | 874 | return 0; |
882 | } | 875 | } |
883 | if (info->port.xmit_buf) | 876 | info->port.xmit_buf = (unsigned char *) page; |
884 | free_page(page); | ||
885 | else | ||
886 | info->port.xmit_buf = (unsigned char *) page; | ||
887 | 877 | ||
888 | /* | 878 | /* |
889 | * Clear the FIFO buffers and disable them | 879 | * Clear the FIFO buffers and disable them |
@@ -951,24 +941,19 @@ static int mxser_startup(struct tty_struct *tty) | |||
951 | * and set the speed of the serial port | 941 | * and set the speed of the serial port |
952 | */ | 942 | */ |
953 | mxser_change_speed(tty, NULL); | 943 | mxser_change_speed(tty, NULL); |
954 | info->port.flags |= ASYNC_INITIALIZED; | ||
955 | spin_unlock_irqrestore(&info->slock, flags); | 944 | spin_unlock_irqrestore(&info->slock, flags); |
956 | 945 | ||
957 | return 0; | 946 | return 0; |
958 | } | 947 | } |
959 | 948 | ||
960 | /* | 949 | /* |
961 | * This routine will shutdown a serial port; interrupts maybe disabled, and | 950 | * This routine will shutdown a serial port |
962 | * DTR is dropped if the hangup on close termio flag is on. | ||
963 | */ | 951 | */ |
964 | static void mxser_shutdown(struct tty_struct *tty) | 952 | static void mxser_shutdown_port(struct tty_port *port) |
965 | { | 953 | { |
966 | struct mxser_port *info = tty->driver_data; | 954 | struct mxser_port *info = container_of(port, struct mxser_port, port); |
967 | unsigned long flags; | 955 | unsigned long flags; |
968 | 956 | ||
969 | if (!(info->port.flags & ASYNC_INITIALIZED)) | ||
970 | return; | ||
971 | |||
972 | spin_lock_irqsave(&info->slock, flags); | 957 | spin_lock_irqsave(&info->slock, flags); |
973 | 958 | ||
974 | /* | 959 | /* |
@@ -978,7 +963,7 @@ static void mxser_shutdown(struct tty_struct *tty) | |||
978 | wake_up_interruptible(&info->port.delta_msr_wait); | 963 | wake_up_interruptible(&info->port.delta_msr_wait); |
979 | 964 | ||
980 | /* | 965 | /* |
981 | * Free the IRQ, if necessary | 966 | * Free the xmit buffer, if necessary |
982 | */ | 967 | */ |
983 | if (info->port.xmit_buf) { | 968 | if (info->port.xmit_buf) { |
984 | free_page((unsigned long) info->port.xmit_buf); | 969 | free_page((unsigned long) info->port.xmit_buf); |
@@ -988,10 +973,6 @@ static void mxser_shutdown(struct tty_struct *tty) | |||
988 | info->IER = 0; | 973 | info->IER = 0; |
989 | outb(0x00, info->ioaddr + UART_IER); | 974 | outb(0x00, info->ioaddr + UART_IER); |
990 | 975 | ||
991 | if (tty->termios->c_cflag & HUPCL) | ||
992 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); | ||
993 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
994 | |||
995 | /* clear Rx/Tx FIFO's */ | 976 | /* clear Rx/Tx FIFO's */ |
996 | if (info->board->chip_flag) | 977 | if (info->board->chip_flag) |
997 | outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | | 978 | outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | |
@@ -1004,9 +985,6 @@ static void mxser_shutdown(struct tty_struct *tty) | |||
1004 | /* read data port to reset things */ | 985 | /* read data port to reset things */ |
1005 | (void) inb(info->ioaddr + UART_RX); | 986 | (void) inb(info->ioaddr + UART_RX); |
1006 | 987 | ||
1007 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
1008 | |||
1009 | info->port.flags &= ~ASYNC_INITIALIZED; | ||
1010 | 988 | ||
1011 | if (info->board->chip_flag) | 989 | if (info->board->chip_flag) |
1012 | SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); | 990 | SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); |
@@ -1023,8 +1001,7 @@ static void mxser_shutdown(struct tty_struct *tty) | |||
1023 | static int mxser_open(struct tty_struct *tty, struct file *filp) | 1001 | static int mxser_open(struct tty_struct *tty, struct file *filp) |
1024 | { | 1002 | { |
1025 | struct mxser_port *info; | 1003 | struct mxser_port *info; |
1026 | unsigned long flags; | 1004 | int line; |
1027 | int retval, line; | ||
1028 | 1005 | ||
1029 | line = tty->index; | 1006 | line = tty->index; |
1030 | if (line == MXSER_PORTS) | 1007 | if (line == MXSER_PORTS) |
@@ -1035,23 +1012,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
1035 | if (!info->ioaddr) | 1012 | if (!info->ioaddr) |
1036 | return -ENODEV; | 1013 | return -ENODEV; |
1037 | 1014 | ||
1038 | tty->driver_data = info; | 1015 | return tty_port_open(&info->port, tty, filp); |
1039 | tty_port_tty_set(&info->port, tty); | ||
1040 | /* | ||
1041 | * Start up serial port | ||
1042 | */ | ||
1043 | spin_lock_irqsave(&info->port.lock, flags); | ||
1044 | info->port.count++; | ||
1045 | spin_unlock_irqrestore(&info->port.lock, flags); | ||
1046 | retval = mxser_startup(tty); | ||
1047 | if (retval) | ||
1048 | return retval; | ||
1049 | |||
1050 | retval = tty_port_block_til_ready(&info->port, tty, filp); | ||
1051 | if (retval) | ||
1052 | return retval; | ||
1053 | |||
1054 | return 0; | ||
1055 | } | 1016 | } |
1056 | 1017 | ||
1057 | static void mxser_flush_buffer(struct tty_struct *tty) | 1018 | static void mxser_flush_buffer(struct tty_struct *tty) |
@@ -1075,19 +1036,11 @@ static void mxser_flush_buffer(struct tty_struct *tty) | |||
1075 | } | 1036 | } |
1076 | 1037 | ||
1077 | 1038 | ||
1078 | static void mxser_close_port(struct tty_struct *tty, struct tty_port *port) | 1039 | static void mxser_close_port(struct tty_port *port) |
1079 | { | 1040 | { |
1080 | struct mxser_port *info = container_of(port, struct mxser_port, port); | 1041 | struct mxser_port *info = container_of(port, struct mxser_port, port); |
1081 | unsigned long timeout; | 1042 | unsigned long timeout; |
1082 | /* | 1043 | /* |
1083 | * Save the termios structure, since this port may have | ||
1084 | * separate termios for callout and dialin. | ||
1085 | * | ||
1086 | * FIXME: Can this go ? | ||
1087 | */ | ||
1088 | if (port->flags & ASYNC_NORMAL_ACTIVE) | ||
1089 | info->normal_termios = *tty->termios; | ||
1090 | /* | ||
1091 | * At this point we stop accepting input. To do this, we | 1044 | * At this point we stop accepting input. To do this, we |
1092 | * disable the receive line status interrupts, and tell the | 1045 | * disable the receive line status interrupts, and tell the |
1093 | * interrupt driver to stop checking the data ready bit in the | 1046 | * interrupt driver to stop checking the data ready bit in the |
@@ -1097,22 +1050,18 @@ static void mxser_close_port(struct tty_struct *tty, struct tty_port *port) | |||
1097 | if (info->board->chip_flag) | 1050 | if (info->board->chip_flag) |
1098 | info->IER &= ~MOXA_MUST_RECV_ISR; | 1051 | info->IER &= ~MOXA_MUST_RECV_ISR; |
1099 | 1052 | ||
1100 | if (port->flags & ASYNC_INITIALIZED) { | 1053 | outb(info->IER, info->ioaddr + UART_IER); |
1101 | outb(info->IER, info->ioaddr + UART_IER); | 1054 | /* |
1102 | /* | 1055 | * Before we drop DTR, make sure the UART transmitter |
1103 | * Before we drop DTR, make sure the UART transmitter | 1056 | * has completely drained; this is especially |
1104 | * has completely drained; this is especially | 1057 | * important if there is a transmit FIFO! |
1105 | * important if there is a transmit FIFO! | 1058 | */ |
1106 | */ | 1059 | timeout = jiffies + HZ; |
1107 | timeout = jiffies + HZ; | 1060 | while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) { |
1108 | while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) { | 1061 | schedule_timeout_interruptible(5); |
1109 | schedule_timeout_interruptible(5); | 1062 | if (time_after(jiffies, timeout)) |
1110 | if (time_after(jiffies, timeout)) | 1063 | break; |
1111 | break; | ||
1112 | } | ||
1113 | } | 1064 | } |
1114 | mxser_shutdown(tty); | ||
1115 | |||
1116 | } | 1065 | } |
1117 | 1066 | ||
1118 | /* | 1067 | /* |
@@ -1130,8 +1079,12 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1130 | return; | 1079 | return; |
1131 | if (tty_port_close_start(port, tty, filp) == 0) | 1080 | if (tty_port_close_start(port, tty, filp) == 0) |
1132 | return; | 1081 | return; |
1133 | mxser_close_port(tty, port); | 1082 | mutex_lock(&port->mutex); |
1083 | mxser_close_port(port); | ||
1134 | mxser_flush_buffer(tty); | 1084 | mxser_flush_buffer(tty); |
1085 | mxser_shutdown_port(port); | ||
1086 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | ||
1087 | mutex_unlock(&port->mutex); | ||
1135 | /* Right now the tty_port set is done outside of the close_end helper | 1088 | /* Right now the tty_port set is done outside of the close_end helper |
1136 | as we don't yet have everyone using refcounts */ | 1089 | as we don't yet have everyone using refcounts */ |
1137 | tty_port_close_end(port, tty); | 1090 | tty_port_close_end(port, tty); |
@@ -1275,6 +1228,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1275 | struct serial_struct __user *new_info) | 1228 | struct serial_struct __user *new_info) |
1276 | { | 1229 | { |
1277 | struct mxser_port *info = tty->driver_data; | 1230 | struct mxser_port *info = tty->driver_data; |
1231 | struct tty_port *port = &info->port; | ||
1278 | struct serial_struct new_serial; | 1232 | struct serial_struct new_serial; |
1279 | speed_t baud; | 1233 | speed_t baud; |
1280 | unsigned long sl_flags; | 1234 | unsigned long sl_flags; |
@@ -1290,7 +1244,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1290 | new_serial.port != info->ioaddr) | 1244 | new_serial.port != info->ioaddr) |
1291 | return -EINVAL; | 1245 | return -EINVAL; |
1292 | 1246 | ||
1293 | flags = info->port.flags & ASYNC_SPD_MASK; | 1247 | flags = port->flags & ASYNC_SPD_MASK; |
1294 | 1248 | ||
1295 | if (!capable(CAP_SYS_ADMIN)) { | 1249 | if (!capable(CAP_SYS_ADMIN)) { |
1296 | if ((new_serial.baud_base != info->baud_base) || | 1250 | if ((new_serial.baud_base != info->baud_base) || |
@@ -1304,16 +1258,17 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1304 | * OK, past this point, all the error checking has been done. | 1258 | * OK, past this point, all the error checking has been done. |
1305 | * At this point, we start making changes..... | 1259 | * At this point, we start making changes..... |
1306 | */ | 1260 | */ |
1307 | info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) | | 1261 | port->flags = ((port->flags & ~ASYNC_FLAGS) | |
1308 | (new_serial.flags & ASYNC_FLAGS)); | 1262 | (new_serial.flags & ASYNC_FLAGS)); |
1309 | info->port.close_delay = new_serial.close_delay * HZ / 100; | 1263 | port->close_delay = new_serial.close_delay * HZ / 100; |
1310 | info->port.closing_wait = new_serial.closing_wait * HZ / 100; | 1264 | port->closing_wait = new_serial.closing_wait * HZ / 100; |
1311 | tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) | 1265 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1312 | ? 1 : 0; | 1266 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && |
1313 | if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && | ||
1314 | (new_serial.baud_base != info->baud_base || | 1267 | (new_serial.baud_base != info->baud_base || |
1315 | new_serial.custom_divisor != | 1268 | new_serial.custom_divisor != |
1316 | info->custom_divisor)) { | 1269 | info->custom_divisor)) { |
1270 | if (new_serial.custom_divisor == 0) | ||
1271 | return -EINVAL; | ||
1317 | baud = new_serial.baud_base / new_serial.custom_divisor; | 1272 | baud = new_serial.baud_base / new_serial.custom_divisor; |
1318 | tty_encode_baud_rate(tty, baud, baud); | 1273 | tty_encode_baud_rate(tty, baud, baud); |
1319 | } | 1274 | } |
@@ -1323,15 +1278,17 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1323 | 1278 | ||
1324 | process_txrx_fifo(info); | 1279 | process_txrx_fifo(info); |
1325 | 1280 | ||
1326 | if (info->port.flags & ASYNC_INITIALIZED) { | 1281 | if (test_bit(ASYNCB_INITIALIZED, &port->flags)) { |
1327 | if (flags != (info->port.flags & ASYNC_SPD_MASK)) { | 1282 | if (flags != (port->flags & ASYNC_SPD_MASK)) { |
1328 | spin_lock_irqsave(&info->slock, sl_flags); | 1283 | spin_lock_irqsave(&info->slock, sl_flags); |
1329 | mxser_change_speed(tty, NULL); | 1284 | mxser_change_speed(tty, NULL); |
1330 | spin_unlock_irqrestore(&info->slock, sl_flags); | 1285 | spin_unlock_irqrestore(&info->slock, sl_flags); |
1331 | } | 1286 | } |
1332 | } else | 1287 | } else { |
1333 | retval = mxser_startup(tty); | 1288 | retval = mxser_activate(port, tty); |
1334 | 1289 | if (retval == 0) | |
1290 | set_bit(ASYNCB_INITIALIZED, &port->flags); | ||
1291 | } | ||
1335 | return retval; | 1292 | return retval; |
1336 | } | 1293 | } |
1337 | 1294 | ||
@@ -1520,7 +1477,8 @@ static int __init mxser_read_register(int port, unsigned short *regs) | |||
1520 | 1477 | ||
1521 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | 1478 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) |
1522 | { | 1479 | { |
1523 | struct mxser_port *port; | 1480 | struct mxser_port *ip; |
1481 | struct tty_port *port; | ||
1524 | struct tty_struct *tty; | 1482 | struct tty_struct *tty; |
1525 | int result, status; | 1483 | int result, status; |
1526 | unsigned int i, j; | 1484 | unsigned int i, j; |
@@ -1536,38 +1494,39 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1536 | 1494 | ||
1537 | case MOXA_CHKPORTENABLE: | 1495 | case MOXA_CHKPORTENABLE: |
1538 | result = 0; | 1496 | result = 0; |
1539 | lock_kernel(); | ||
1540 | for (i = 0; i < MXSER_BOARDS; i++) | 1497 | for (i = 0; i < MXSER_BOARDS; i++) |
1541 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) | 1498 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) |
1542 | if (mxser_boards[i].ports[j].ioaddr) | 1499 | if (mxser_boards[i].ports[j].ioaddr) |
1543 | result |= (1 << i); | 1500 | result |= (1 << i); |
1544 | unlock_kernel(); | ||
1545 | return put_user(result, (unsigned long __user *)argp); | 1501 | return put_user(result, (unsigned long __user *)argp); |
1546 | case MOXA_GETDATACOUNT: | 1502 | case MOXA_GETDATACOUNT: |
1547 | lock_kernel(); | 1503 | /* The receive side is locked by port->slock but it isn't |
1504 | clear that an exact snapshot is worth copying here */ | ||
1548 | if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) | 1505 | if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) |
1549 | ret = -EFAULT; | 1506 | ret = -EFAULT; |
1550 | unlock_kernel(); | ||
1551 | return ret; | 1507 | return ret; |
1552 | case MOXA_GETMSTATUS: { | 1508 | case MOXA_GETMSTATUS: { |
1553 | struct mxser_mstatus ms, __user *msu = argp; | 1509 | struct mxser_mstatus ms, __user *msu = argp; |
1554 | lock_kernel(); | ||
1555 | for (i = 0; i < MXSER_BOARDS; i++) | 1510 | for (i = 0; i < MXSER_BOARDS; i++) |
1556 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | 1511 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { |
1557 | port = &mxser_boards[i].ports[j]; | 1512 | ip = &mxser_boards[i].ports[j]; |
1513 | port = &ip->port; | ||
1558 | memset(&ms, 0, sizeof(ms)); | 1514 | memset(&ms, 0, sizeof(ms)); |
1559 | 1515 | ||
1560 | if (!port->ioaddr) | 1516 | mutex_lock(&port->mutex); |
1517 | if (!ip->ioaddr) | ||
1561 | goto copy; | 1518 | goto copy; |
1562 | 1519 | ||
1563 | tty = tty_port_tty_get(&port->port); | 1520 | tty = tty_port_tty_get(port); |
1564 | 1521 | ||
1565 | if (!tty || !tty->termios) | 1522 | if (!tty || !tty->termios) |
1566 | ms.cflag = port->normal_termios.c_cflag; | 1523 | ms.cflag = ip->normal_termios.c_cflag; |
1567 | else | 1524 | else |
1568 | ms.cflag = tty->termios->c_cflag; | 1525 | ms.cflag = tty->termios->c_cflag; |
1569 | tty_kref_put(tty); | 1526 | tty_kref_put(tty); |
1570 | status = inb(port->ioaddr + UART_MSR); | 1527 | spin_lock_irq(&ip->slock); |
1528 | status = inb(ip->ioaddr + UART_MSR); | ||
1529 | spin_unlock_irq(&ip->slock); | ||
1571 | if (status & UART_MSR_DCD) | 1530 | if (status & UART_MSR_DCD) |
1572 | ms.dcd = 1; | 1531 | ms.dcd = 1; |
1573 | if (status & UART_MSR_DSR) | 1532 | if (status & UART_MSR_DSR) |
@@ -1575,13 +1534,11 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1575 | if (status & UART_MSR_CTS) | 1534 | if (status & UART_MSR_CTS) |
1576 | ms.cts = 1; | 1535 | ms.cts = 1; |
1577 | copy: | 1536 | copy: |
1578 | if (copy_to_user(msu, &ms, sizeof(ms))) { | 1537 | mutex_unlock(&port->mutex); |
1579 | unlock_kernel(); | 1538 | if (copy_to_user(msu, &ms, sizeof(ms))) |
1580 | return -EFAULT; | 1539 | return -EFAULT; |
1581 | } | ||
1582 | msu++; | 1540 | msu++; |
1583 | } | 1541 | } |
1584 | unlock_kernel(); | ||
1585 | return 0; | 1542 | return 0; |
1586 | } | 1543 | } |
1587 | case MOXA_ASPP_MON_EXT: { | 1544 | case MOXA_ASPP_MON_EXT: { |
@@ -1593,41 +1550,48 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1593 | if (!me) | 1550 | if (!me) |
1594 | return -ENOMEM; | 1551 | return -ENOMEM; |
1595 | 1552 | ||
1596 | lock_kernel(); | ||
1597 | for (i = 0, p = 0; i < MXSER_BOARDS; i++) { | 1553 | for (i = 0, p = 0; i < MXSER_BOARDS; i++) { |
1598 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) { | 1554 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++, p++) { |
1599 | if (p >= ARRAY_SIZE(me->rx_cnt)) { | 1555 | if (p >= ARRAY_SIZE(me->rx_cnt)) { |
1600 | i = MXSER_BOARDS; | 1556 | i = MXSER_BOARDS; |
1601 | break; | 1557 | break; |
1602 | } | 1558 | } |
1603 | port = &mxser_boards[i].ports[j]; | 1559 | ip = &mxser_boards[i].ports[j]; |
1604 | if (!port->ioaddr) | 1560 | port = &ip->port; |
1561 | |||
1562 | mutex_lock(&port->mutex); | ||
1563 | if (!ip->ioaddr) { | ||
1564 | mutex_unlock(&port->mutex); | ||
1605 | continue; | 1565 | continue; |
1566 | } | ||
1606 | 1567 | ||
1607 | status = mxser_get_msr(port->ioaddr, 0, p); | 1568 | spin_lock_irq(&ip->slock); |
1569 | status = mxser_get_msr(ip->ioaddr, 0, p); | ||
1608 | 1570 | ||
1609 | if (status & UART_MSR_TERI) | 1571 | if (status & UART_MSR_TERI) |
1610 | port->icount.rng++; | 1572 | ip->icount.rng++; |
1611 | if (status & UART_MSR_DDSR) | 1573 | if (status & UART_MSR_DDSR) |
1612 | port->icount.dsr++; | 1574 | ip->icount.dsr++; |
1613 | if (status & UART_MSR_DDCD) | 1575 | if (status & UART_MSR_DDCD) |
1614 | port->icount.dcd++; | 1576 | ip->icount.dcd++; |
1615 | if (status & UART_MSR_DCTS) | 1577 | if (status & UART_MSR_DCTS) |
1616 | port->icount.cts++; | 1578 | ip->icount.cts++; |
1617 | 1579 | ||
1618 | port->mon_data.modem_status = status; | 1580 | ip->mon_data.modem_status = status; |
1619 | me->rx_cnt[p] = port->mon_data.rxcnt; | 1581 | me->rx_cnt[p] = ip->mon_data.rxcnt; |
1620 | me->tx_cnt[p] = port->mon_data.txcnt; | 1582 | me->tx_cnt[p] = ip->mon_data.txcnt; |
1621 | me->up_rxcnt[p] = port->mon_data.up_rxcnt; | 1583 | me->up_rxcnt[p] = ip->mon_data.up_rxcnt; |
1622 | me->up_txcnt[p] = port->mon_data.up_txcnt; | 1584 | me->up_txcnt[p] = ip->mon_data.up_txcnt; |
1623 | me->modem_status[p] = | 1585 | me->modem_status[p] = |
1624 | port->mon_data.modem_status; | 1586 | ip->mon_data.modem_status; |
1625 | tty = tty_port_tty_get(&port->port); | 1587 | spin_unlock_irq(&ip->slock); |
1588 | |||
1589 | tty = tty_port_tty_get(&ip->port); | ||
1626 | 1590 | ||
1627 | if (!tty || !tty->termios) { | 1591 | if (!tty || !tty->termios) { |
1628 | cflag = port->normal_termios.c_cflag; | 1592 | cflag = ip->normal_termios.c_cflag; |
1629 | iflag = port->normal_termios.c_iflag; | 1593 | iflag = ip->normal_termios.c_iflag; |
1630 | me->baudrate[p] = tty_termios_baud_rate(&port->normal_termios); | 1594 | me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios); |
1631 | } else { | 1595 | } else { |
1632 | cflag = tty->termios->c_cflag; | 1596 | cflag = tty->termios->c_cflag; |
1633 | iflag = tty->termios->c_iflag; | 1597 | iflag = tty->termios->c_iflag; |
@@ -1646,16 +1610,15 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1646 | if (iflag & (IXON | IXOFF)) | 1610 | if (iflag & (IXON | IXOFF)) |
1647 | me->flowctrl[p] |= 0x0C; | 1611 | me->flowctrl[p] |= 0x0C; |
1648 | 1612 | ||
1649 | if (port->type == PORT_16550A) | 1613 | if (ip->type == PORT_16550A) |
1650 | me->fifo[p] = 1; | 1614 | me->fifo[p] = 1; |
1651 | 1615 | ||
1652 | opmode = inb(port->opmode_ioaddr) >> | 1616 | opmode = inb(ip->opmode_ioaddr)>>((p % 4) * 2); |
1653 | ((p % 4) * 2); | ||
1654 | opmode &= OP_MODE_MASK; | 1617 | opmode &= OP_MODE_MASK; |
1655 | me->iftype[p] = opmode; | 1618 | me->iftype[p] = opmode; |
1619 | mutex_unlock(&port->mutex); | ||
1656 | } | 1620 | } |
1657 | } | 1621 | } |
1658 | unlock_kernel(); | ||
1659 | if (copy_to_user(argp, me, sizeof(*me))) | 1622 | if (copy_to_user(argp, me, sizeof(*me))) |
1660 | ret = -EFAULT; | 1623 | ret = -EFAULT; |
1661 | kfree(me); | 1624 | kfree(me); |
@@ -1692,6 +1655,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1692 | unsigned int cmd, unsigned long arg) | 1655 | unsigned int cmd, unsigned long arg) |
1693 | { | 1656 | { |
1694 | struct mxser_port *info = tty->driver_data; | 1657 | struct mxser_port *info = tty->driver_data; |
1658 | struct tty_port *port = &info->port; | ||
1695 | struct async_icount cnow; | 1659 | struct async_icount cnow; |
1696 | unsigned long flags; | 1660 | unsigned long flags; |
1697 | void __user *argp = (void __user *)arg; | 1661 | void __user *argp = (void __user *)arg; |
@@ -1716,20 +1680,20 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1716 | opmode != RS422_MODE && | 1680 | opmode != RS422_MODE && |
1717 | opmode != RS485_4WIRE_MODE) | 1681 | opmode != RS485_4WIRE_MODE) |
1718 | return -EFAULT; | 1682 | return -EFAULT; |
1719 | lock_kernel(); | ||
1720 | mask = ModeMask[p]; | 1683 | mask = ModeMask[p]; |
1721 | shiftbit = p * 2; | 1684 | shiftbit = p * 2; |
1685 | spin_lock_irq(&info->slock); | ||
1722 | val = inb(info->opmode_ioaddr); | 1686 | val = inb(info->opmode_ioaddr); |
1723 | val &= mask; | 1687 | val &= mask; |
1724 | val |= (opmode << shiftbit); | 1688 | val |= (opmode << shiftbit); |
1725 | outb(val, info->opmode_ioaddr); | 1689 | outb(val, info->opmode_ioaddr); |
1726 | unlock_kernel(); | 1690 | spin_unlock_irq(&info->slock); |
1727 | } else { | 1691 | } else { |
1728 | lock_kernel(); | ||
1729 | shiftbit = p * 2; | 1692 | shiftbit = p * 2; |
1693 | spin_lock_irq(&info->slock); | ||
1730 | opmode = inb(info->opmode_ioaddr) >> shiftbit; | 1694 | opmode = inb(info->opmode_ioaddr) >> shiftbit; |
1695 | spin_unlock_irq(&info->slock); | ||
1731 | opmode &= OP_MODE_MASK; | 1696 | opmode &= OP_MODE_MASK; |
1732 | unlock_kernel(); | ||
1733 | if (put_user(opmode, (int __user *)argp)) | 1697 | if (put_user(opmode, (int __user *)argp)) |
1734 | return -EFAULT; | 1698 | return -EFAULT; |
1735 | } | 1699 | } |
@@ -1742,14 +1706,14 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1742 | 1706 | ||
1743 | switch (cmd) { | 1707 | switch (cmd) { |
1744 | case TIOCGSERIAL: | 1708 | case TIOCGSERIAL: |
1745 | lock_kernel(); | 1709 | mutex_lock(&port->mutex); |
1746 | retval = mxser_get_serial_info(tty, argp); | 1710 | retval = mxser_get_serial_info(tty, argp); |
1747 | unlock_kernel(); | 1711 | mutex_unlock(&port->mutex); |
1748 | return retval; | 1712 | return retval; |
1749 | case TIOCSSERIAL: | 1713 | case TIOCSSERIAL: |
1750 | lock_kernel(); | 1714 | mutex_lock(&port->mutex); |
1751 | retval = mxser_set_serial_info(tty, argp); | 1715 | retval = mxser_set_serial_info(tty, argp); |
1752 | unlock_kernel(); | 1716 | mutex_unlock(&port->mutex); |
1753 | return retval; | 1717 | return retval; |
1754 | case TIOCSERGETLSR: /* Get line status register */ | 1718 | case TIOCSERGETLSR: /* Get line status register */ |
1755 | return mxser_get_lsr_info(info, argp); | 1719 | return mxser_get_lsr_info(info, argp); |
@@ -1795,31 +1759,33 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1795 | case MOXA_HighSpeedOn: | 1759 | case MOXA_HighSpeedOn: |
1796 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); | 1760 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); |
1797 | case MOXA_SDS_RSTICOUNTER: | 1761 | case MOXA_SDS_RSTICOUNTER: |
1798 | lock_kernel(); | 1762 | spin_lock_irq(&info->slock); |
1799 | info->mon_data.rxcnt = 0; | 1763 | info->mon_data.rxcnt = 0; |
1800 | info->mon_data.txcnt = 0; | 1764 | info->mon_data.txcnt = 0; |
1801 | unlock_kernel(); | 1765 | spin_unlock_irq(&info->slock); |
1802 | return 0; | 1766 | return 0; |
1803 | 1767 | ||
1804 | case MOXA_ASPP_OQUEUE:{ | 1768 | case MOXA_ASPP_OQUEUE:{ |
1805 | int len, lsr; | 1769 | int len, lsr; |
1806 | 1770 | ||
1807 | lock_kernel(); | ||
1808 | len = mxser_chars_in_buffer(tty); | 1771 | len = mxser_chars_in_buffer(tty); |
1772 | spin_lock(&info->slock); | ||
1809 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE; | 1773 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE; |
1774 | spin_unlock_irq(&info->slock); | ||
1810 | len += (lsr ? 0 : 1); | 1775 | len += (lsr ? 0 : 1); |
1811 | unlock_kernel(); | ||
1812 | 1776 | ||
1813 | return put_user(len, (int __user *)argp); | 1777 | return put_user(len, (int __user *)argp); |
1814 | } | 1778 | } |
1815 | case MOXA_ASPP_MON: { | 1779 | case MOXA_ASPP_MON: { |
1816 | int mcr, status; | 1780 | int mcr, status; |
1817 | 1781 | ||
1818 | lock_kernel(); | 1782 | spin_lock(&info->slock); |
1819 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | 1783 | status = mxser_get_msr(info->ioaddr, 1, tty->index); |
1820 | mxser_check_modem_status(tty, info, status); | 1784 | mxser_check_modem_status(tty, info, status); |
1821 | 1785 | ||
1822 | mcr = inb(info->ioaddr + UART_MCR); | 1786 | mcr = inb(info->ioaddr + UART_MCR); |
1787 | spin_unlock(&info->slock); | ||
1788 | |||
1823 | if (mcr & MOXA_MUST_MCR_XON_FLAG) | 1789 | if (mcr & MOXA_MUST_MCR_XON_FLAG) |
1824 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; | 1790 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; |
1825 | else | 1791 | else |
@@ -1834,7 +1800,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1834 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | 1800 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; |
1835 | else | 1801 | else |
1836 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | 1802 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; |
1837 | unlock_kernel(); | 1803 | |
1838 | if (copy_to_user(argp, &info->mon_data, | 1804 | if (copy_to_user(argp, &info->mon_data, |
1839 | sizeof(struct mxser_mon))) | 1805 | sizeof(struct mxser_mon))) |
1840 | return -EFAULT; | 1806 | return -EFAULT; |
@@ -1993,6 +1959,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1993 | { | 1959 | { |
1994 | struct mxser_port *info = tty->driver_data; | 1960 | struct mxser_port *info = tty->driver_data; |
1995 | unsigned long orig_jiffies, char_time; | 1961 | unsigned long orig_jiffies, char_time; |
1962 | unsigned long flags; | ||
1996 | int lsr; | 1963 | int lsr; |
1997 | 1964 | ||
1998 | if (info->type == PORT_UNKNOWN) | 1965 | if (info->type == PORT_UNKNOWN) |
@@ -2032,19 +1999,21 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2032 | timeout, char_time); | 1999 | timeout, char_time); |
2033 | printk("jiff=%lu...", jiffies); | 2000 | printk("jiff=%lu...", jiffies); |
2034 | #endif | 2001 | #endif |
2035 | lock_kernel(); | 2002 | spin_lock_irqsave(&info->slock, flags); |
2036 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { | 2003 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { |
2037 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 2004 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
2038 | printk("lsr = %d (jiff=%lu)...", lsr, jiffies); | 2005 | printk("lsr = %d (jiff=%lu)...", lsr, jiffies); |
2039 | #endif | 2006 | #endif |
2007 | spin_unlock_irqrestore(&info->slock, flags); | ||
2040 | schedule_timeout_interruptible(char_time); | 2008 | schedule_timeout_interruptible(char_time); |
2009 | spin_lock_irqsave(&info->slock, flags); | ||
2041 | if (signal_pending(current)) | 2010 | if (signal_pending(current)) |
2042 | break; | 2011 | break; |
2043 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 2012 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
2044 | break; | 2013 | break; |
2045 | } | 2014 | } |
2015 | spin_unlock_irqrestore(&info->slock, flags); | ||
2046 | set_current_state(TASK_RUNNING); | 2016 | set_current_state(TASK_RUNNING); |
2047 | unlock_kernel(); | ||
2048 | 2017 | ||
2049 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 2018 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
2050 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 2019 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
@@ -2059,7 +2028,6 @@ static void mxser_hangup(struct tty_struct *tty) | |||
2059 | struct mxser_port *info = tty->driver_data; | 2028 | struct mxser_port *info = tty->driver_data; |
2060 | 2029 | ||
2061 | mxser_flush_buffer(tty); | 2030 | mxser_flush_buffer(tty); |
2062 | mxser_shutdown(tty); | ||
2063 | tty_port_hangup(&info->port); | 2031 | tty_port_hangup(&info->port); |
2064 | } | 2032 | } |
2065 | 2033 | ||
@@ -2363,6 +2331,8 @@ static const struct tty_operations mxser_ops = { | |||
2363 | struct tty_port_operations mxser_port_ops = { | 2331 | struct tty_port_operations mxser_port_ops = { |
2364 | .carrier_raised = mxser_carrier_raised, | 2332 | .carrier_raised = mxser_carrier_raised, |
2365 | .dtr_rts = mxser_dtr_rts, | 2333 | .dtr_rts = mxser_dtr_rts, |
2334 | .activate = mxser_activate, | ||
2335 | .shutdown = mxser_shutdown_port, | ||
2366 | }; | 2336 | }; |
2367 | 2337 | ||
2368 | /* | 2338 | /* |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 6934025a1ac1..c1d8b54c816d 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -602,7 +602,7 @@ static void receive_char(struct r3964_info *pInfo, const unsigned char c) | |||
602 | } | 602 | } |
603 | break; | 603 | break; |
604 | case R3964_WAIT_FOR_RX_REPEAT: | 604 | case R3964_WAIT_FOR_RX_REPEAT: |
605 | /* FALLTROUGH */ | 605 | /* FALLTHROUGH */ |
606 | case R3964_IDLE: | 606 | case R3964_IDLE: |
607 | if (c == STX) { | 607 | if (c == STX) { |
608 | /* Prevent rx_queue from overflow: */ | 608 | /* Prevent rx_queue from overflow: */ |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index d3400b20444f..7d73cd430340 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -358,7 +358,7 @@ struct port { | |||
358 | u8 update_flow_control; | 358 | u8 update_flow_control; |
359 | struct ctrl_ul ctrl_ul; | 359 | struct ctrl_ul ctrl_ul; |
360 | struct ctrl_dl ctrl_dl; | 360 | struct ctrl_dl ctrl_dl; |
361 | struct kfifo *fifo_ul; | 361 | struct kfifo fifo_ul; |
362 | void __iomem *dl_addr[2]; | 362 | void __iomem *dl_addr[2]; |
363 | u32 dl_size[2]; | 363 | u32 dl_size[2]; |
364 | u8 toggle_dl; | 364 | u8 toggle_dl; |
@@ -685,8 +685,6 @@ static int nozomi_read_config_table(struct nozomi *dc) | |||
685 | dump_table(dc); | 685 | dump_table(dc); |
686 | 686 | ||
687 | for (i = PORT_MDM; i < MAX_PORT; i++) { | 687 | for (i = PORT_MDM; i < MAX_PORT; i++) { |
688 | dc->port[i].fifo_ul = | ||
689 | kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL); | ||
690 | memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); | 688 | memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); |
691 | memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); | 689 | memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); |
692 | } | 690 | } |
@@ -798,7 +796,7 @@ static int send_data(enum port_type index, struct nozomi *dc) | |||
798 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 796 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
799 | 797 | ||
800 | /* Get data from tty and place in buf for now */ | 798 | /* Get data from tty and place in buf for now */ |
801 | size = __kfifo_get(port->fifo_ul, dc->send_buf, | 799 | size = kfifo_out(&port->fifo_ul, dc->send_buf, |
802 | ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); | 800 | ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); |
803 | 801 | ||
804 | if (size == 0) { | 802 | if (size == 0) { |
@@ -988,11 +986,11 @@ static int receive_flow_control(struct nozomi *dc) | |||
988 | 986 | ||
989 | } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { | 987 | } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { |
990 | 988 | ||
991 | if (__kfifo_len(dc->port[port].fifo_ul)) { | 989 | if (kfifo_len(&dc->port[port].fifo_ul)) { |
992 | DBG1("Enable interrupt (0x%04X) on port: %d", | 990 | DBG1("Enable interrupt (0x%04X) on port: %d", |
993 | enable_ier, port); | 991 | enable_ier, port); |
994 | DBG1("Data in buffer [%d], enable transmit! ", | 992 | DBG1("Data in buffer [%d], enable transmit! ", |
995 | __kfifo_len(dc->port[port].fifo_ul)); | 993 | kfifo_len(&dc->port[port].fifo_ul)); |
996 | enable_transmit_ul(port, dc); | 994 | enable_transmit_ul(port, dc); |
997 | } else { | 995 | } else { |
998 | DBG1("No data in buffer..."); | 996 | DBG1("No data in buffer..."); |
@@ -1433,6 +1431,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1433 | goto err_free_sbuf; | 1431 | goto err_free_sbuf; |
1434 | } | 1432 | } |
1435 | 1433 | ||
1434 | for (i = PORT_MDM; i < MAX_PORT; i++) { | ||
1435 | if (kfifo_alloc(&dc->port[i].fifo_ul, | ||
1436 | FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) { | ||
1437 | dev_err(&pdev->dev, | ||
1438 | "Could not allocate kfifo buffer\n"); | ||
1439 | ret = -ENOMEM; | ||
1440 | goto err_free_kfifo; | ||
1441 | } | ||
1442 | } | ||
1443 | |||
1436 | spin_lock_init(&dc->spin_mutex); | 1444 | spin_lock_init(&dc->spin_mutex); |
1437 | 1445 | ||
1438 | nozomi_setup_private_data(dc); | 1446 | nozomi_setup_private_data(dc); |
@@ -1445,7 +1453,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1445 | NOZOMI_NAME, dc); | 1453 | NOZOMI_NAME, dc); |
1446 | if (unlikely(ret)) { | 1454 | if (unlikely(ret)) { |
1447 | dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); | 1455 | dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); |
1448 | goto err_free_sbuf; | 1456 | goto err_free_kfifo; |
1449 | } | 1457 | } |
1450 | 1458 | ||
1451 | DBG1("base_addr: %p", dc->base_addr); | 1459 | DBG1("base_addr: %p", dc->base_addr); |
@@ -1464,13 +1472,28 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1464 | dc->state = NOZOMI_STATE_ENABLED; | 1472 | dc->state = NOZOMI_STATE_ENABLED; |
1465 | 1473 | ||
1466 | for (i = 0; i < MAX_PORT; i++) { | 1474 | for (i = 0; i < MAX_PORT; i++) { |
1475 | struct device *tty_dev; | ||
1476 | |||
1467 | mutex_init(&dc->port[i].tty_sem); | 1477 | mutex_init(&dc->port[i].tty_sem); |
1468 | tty_port_init(&dc->port[i].port); | 1478 | tty_port_init(&dc->port[i].port); |
1469 | tty_register_device(ntty_driver, dc->index_start + i, | 1479 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, |
1470 | &pdev->dev); | 1480 | &pdev->dev); |
1481 | |||
1482 | if (IS_ERR(tty_dev)) { | ||
1483 | ret = PTR_ERR(tty_dev); | ||
1484 | dev_err(&pdev->dev, "Could not allocate tty?\n"); | ||
1485 | goto err_free_tty; | ||
1486 | } | ||
1471 | } | 1487 | } |
1488 | |||
1472 | return 0; | 1489 | return 0; |
1473 | 1490 | ||
1491 | err_free_tty: | ||
1492 | for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) | ||
1493 | tty_unregister_device(ntty_driver, i); | ||
1494 | err_free_kfifo: | ||
1495 | for (i = 0; i < MAX_PORT; i++) | ||
1496 | kfifo_free(&dc->port[i].fifo_ul); | ||
1474 | err_free_sbuf: | 1497 | err_free_sbuf: |
1475 | kfree(dc->send_buf); | 1498 | kfree(dc->send_buf); |
1476 | iounmap(dc->base_addr); | 1499 | iounmap(dc->base_addr); |
@@ -1536,8 +1559,7 @@ static void __devexit nozomi_card_exit(struct pci_dev *pdev) | |||
1536 | free_irq(pdev->irq, dc); | 1559 | free_irq(pdev->irq, dc); |
1537 | 1560 | ||
1538 | for (i = 0; i < MAX_PORT; i++) | 1561 | for (i = 0; i < MAX_PORT; i++) |
1539 | if (dc->port[i].fifo_ul) | 1562 | kfifo_free(&dc->port[i].fifo_ul); |
1540 | kfifo_free(dc->port[i].fifo_ul); | ||
1541 | 1563 | ||
1542 | kfree(dc->send_buf); | 1564 | kfree(dc->send_buf); |
1543 | 1565 | ||
@@ -1673,7 +1695,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1673 | goto exit; | 1695 | goto exit; |
1674 | } | 1696 | } |
1675 | 1697 | ||
1676 | rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count); | 1698 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); |
1677 | 1699 | ||
1678 | /* notify card */ | 1700 | /* notify card */ |
1679 | if (unlikely(dc == NULL)) { | 1701 | if (unlikely(dc == NULL)) { |
@@ -1721,7 +1743,7 @@ static int ntty_write_room(struct tty_struct *tty) | |||
1721 | if (!port->port.count) | 1743 | if (!port->port.count) |
1722 | goto exit; | 1744 | goto exit; |
1723 | 1745 | ||
1724 | room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); | 1746 | room = port->fifo_ul.size - kfifo_len(&port->fifo_ul); |
1725 | 1747 | ||
1726 | exit: | 1748 | exit: |
1727 | mutex_unlock(&port->tty_sem); | 1749 | mutex_unlock(&port->tty_sem); |
@@ -1878,7 +1900,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) | |||
1878 | goto exit_in_buffer; | 1900 | goto exit_in_buffer; |
1879 | } | 1901 | } |
1880 | 1902 | ||
1881 | rval = __kfifo_len(port->fifo_ul); | 1903 | rval = kfifo_len(&port->fifo_ul); |
1882 | 1904 | ||
1883 | exit_in_buffer: | 1905 | exit_in_buffer: |
1884 | return rval; | 1906 | return rval; |
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 88cee4099be9..fdbcc9fd6d31 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #define NVRAM_VERSION "1.3" | 38 | #define NVRAM_VERSION "1.3" |
39 | 39 | ||
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | #include <linux/smp_lock.h> | ||
42 | #include <linux/nvram.h> | 41 | #include <linux/nvram.h> |
43 | 42 | ||
44 | #define PC 1 | 43 | #define PC 1 |
@@ -111,6 +110,7 @@ | |||
111 | #include <linux/spinlock.h> | 110 | #include <linux/spinlock.h> |
112 | #include <linux/io.h> | 111 | #include <linux/io.h> |
113 | #include <linux/uaccess.h> | 112 | #include <linux/uaccess.h> |
113 | #include <linux/smp_lock.h> | ||
114 | 114 | ||
115 | #include <asm/system.h> | 115 | #include <asm/system.h> |
116 | 116 | ||
@@ -214,7 +214,6 @@ void nvram_set_checksum(void) | |||
214 | 214 | ||
215 | static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) | 215 | static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) |
216 | { | 216 | { |
217 | lock_kernel(); | ||
218 | switch (origin) { | 217 | switch (origin) { |
219 | case 0: | 218 | case 0: |
220 | /* nothing to do */ | 219 | /* nothing to do */ |
@@ -226,7 +225,7 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) | |||
226 | offset += NVRAM_BYTES; | 225 | offset += NVRAM_BYTES; |
227 | break; | 226 | break; |
228 | } | 227 | } |
229 | unlock_kernel(); | 228 | |
230 | return (offset >= 0) ? (file->f_pos = offset) : -EINVAL; | 229 | return (offset >= 0) ? (file->f_pos = offset) : -EINVAL; |
231 | } | 230 | } |
232 | 231 | ||
@@ -265,10 +264,16 @@ static ssize_t nvram_write(struct file *file, const char __user *buf, | |||
265 | unsigned char contents[NVRAM_BYTES]; | 264 | unsigned char contents[NVRAM_BYTES]; |
266 | unsigned i = *ppos; | 265 | unsigned i = *ppos; |
267 | unsigned char *tmp; | 266 | unsigned char *tmp; |
268 | int len; | ||
269 | 267 | ||
270 | len = (NVRAM_BYTES - i) < count ? (NVRAM_BYTES - i) : count; | 268 | if (i >= NVRAM_BYTES) |
271 | if (copy_from_user(contents, buf, len)) | 269 | return 0; /* Past EOF */ |
270 | |||
271 | if (count > NVRAM_BYTES - i) | ||
272 | count = NVRAM_BYTES - i; | ||
273 | if (count > NVRAM_BYTES) | ||
274 | return -EFAULT; /* Can't happen, but prove it to gcc */ | ||
275 | |||
276 | if (copy_from_user(contents, buf, count)) | ||
272 | return -EFAULT; | 277 | return -EFAULT; |
273 | 278 | ||
274 | spin_lock_irq(&rtc_lock); | 279 | spin_lock_irq(&rtc_lock); |
@@ -276,7 +281,7 @@ static ssize_t nvram_write(struct file *file, const char __user *buf, | |||
276 | if (!__nvram_check_checksum()) | 281 | if (!__nvram_check_checksum()) |
277 | goto checksum_err; | 282 | goto checksum_err; |
278 | 283 | ||
279 | for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp) | 284 | for (tmp = contents; count--; ++i, ++tmp) |
280 | __nvram_write_byte(*tmp, i); | 285 | __nvram_write_byte(*tmp, i); |
281 | 286 | ||
282 | __nvram_set_checksum(); | 287 | __nvram_set_checksum(); |
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index 8c7df5ba088f..f80810901db6 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/smp_lock.h> | 28 | #include <linux/smp_lock.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/jiffies.h> | ||
30 | 31 | ||
31 | #include <asm/hardware/dec21285.h> | 32 | #include <asm/hardware/dec21285.h> |
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 3f7da8cf3a80..8ecbcc174c15 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #include <linux/nsc_gpio.h> | 21 | #include <linux/nsc_gpio.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/smp_lock.h> | ||
24 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
25 | 24 | ||
26 | #define DEVNAME "pc8736x_gpio" | 25 | #define DEVNAME "pc8736x_gpio" |
@@ -223,7 +222,6 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file) | |||
223 | unsigned m = iminor(inode); | 222 | unsigned m = iminor(inode); |
224 | file->private_data = &pc8736x_gpio_ops; | 223 | file->private_data = &pc8736x_gpio_ops; |
225 | 224 | ||
226 | cycle_kernel_lock(); | ||
227 | dev_dbg(&pdev->dev, "open %d\n", m); | 225 | dev_dbg(&pdev->dev, "open %d\n", m); |
228 | 226 | ||
229 | if (m >= PC8736X_GPIO_CT) | 227 | if (m >= PC8736X_GPIO_CT) |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index c250a31efa53..2db4c0a29b05 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -23,8 +23,6 @@ | |||
23 | * All rights reserved. Licensed under dual BSD/GPL license. | 23 | * All rights reserved. Licensed under dual BSD/GPL license. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | /* #define PCMCIA_DEBUG 6 */ | ||
27 | |||
28 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 27 | #include <linux/module.h> |
30 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
@@ -47,18 +45,17 @@ | |||
47 | 45 | ||
48 | /* #define ATR_CSUM */ | 46 | /* #define ATR_CSUM */ |
49 | 47 | ||
50 | #ifdef PCMCIA_DEBUG | 48 | #define reader_to_dev(x) (&x->p_dev->dev) |
51 | #define reader_to_dev(x) (&handle_to_dev(x->p_dev)) | 49 | |
52 | static int pc_debug = PCMCIA_DEBUG; | 50 | /* n (debug level) is ignored */ |
53 | module_param(pc_debug, int, 0600); | 51 | /* additional debug output may be enabled by re-compiling with |
54 | #define DEBUGP(n, rdr, x, args...) do { \ | 52 | * CM4000_DEBUG set */ |
55 | if (pc_debug >= (n)) \ | 53 | /* #define CM4000_DEBUG */ |
56 | dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ | 54 | #define DEBUGP(n, rdr, x, args...) do { \ |
57 | __func__ , ## args); \ | 55 | dev_dbg(reader_to_dev(rdr), "%s:" x, \ |
56 | __func__ , ## args); \ | ||
58 | } while (0) | 57 | } while (0) |
59 | #else | 58 | |
60 | #define DEBUGP(n, rdr, x, args...) | ||
61 | #endif | ||
62 | static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte"; | 59 | static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte"; |
63 | 60 | ||
64 | #define T_1SEC (HZ) | 61 | #define T_1SEC (HZ) |
@@ -174,14 +171,13 @@ static unsigned char fi_di_table[10][14] = { | |||
174 | /* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9} | 171 | /* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9} |
175 | }; | 172 | }; |
176 | 173 | ||
177 | #ifndef PCMCIA_DEBUG | 174 | #ifndef CM4000_DEBUG |
178 | #define xoutb outb | 175 | #define xoutb outb |
179 | #define xinb inb | 176 | #define xinb inb |
180 | #else | 177 | #else |
181 | static inline void xoutb(unsigned char val, unsigned short port) | 178 | static inline void xoutb(unsigned char val, unsigned short port) |
182 | { | 179 | { |
183 | if (pc_debug >= 7) | 180 | pr_debug("outb(val=%.2x,port=%.4x)\n", val, port); |
184 | printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port); | ||
185 | outb(val, port); | 181 | outb(val, port); |
186 | } | 182 | } |
187 | static inline unsigned char xinb(unsigned short port) | 183 | static inline unsigned char xinb(unsigned short port) |
@@ -189,8 +185,7 @@ static inline unsigned char xinb(unsigned short port) | |||
189 | unsigned char val; | 185 | unsigned char val; |
190 | 186 | ||
191 | val = inb(port); | 187 | val = inb(port); |
192 | if (pc_debug >= 7) | 188 | pr_debug("%.2x=inb(%.4x)\n", val, port); |
193 | printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port); | ||
194 | 189 | ||
195 | return val; | 190 | return val; |
196 | } | 191 | } |
@@ -514,12 +509,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) | |||
514 | for (i = 0; i < 4; i++) { | 509 | for (i = 0; i < 4; i++) { |
515 | xoutb(i, REG_BUF_ADDR(iobase)); | 510 | xoutb(i, REG_BUF_ADDR(iobase)); |
516 | xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */ | 511 | xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */ |
517 | #ifdef PCMCIA_DEBUG | 512 | #ifdef CM4000_DEBUG |
518 | if (pc_debug >= 5) | 513 | pr_debug("0x%.2x ", dev->pts[i]); |
519 | printk("0x%.2x ", dev->pts[i]); | ||
520 | } | 514 | } |
521 | if (pc_debug >= 5) | 515 | pr_debug("\n"); |
522 | printk("\n"); | ||
523 | #else | 516 | #else |
524 | } | 517 | } |
525 | #endif | 518 | #endif |
@@ -579,14 +572,13 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) | |||
579 | pts_reply[i] = inb(REG_BUF_DATA(iobase)); | 572 | pts_reply[i] = inb(REG_BUF_DATA(iobase)); |
580 | } | 573 | } |
581 | 574 | ||
582 | #ifdef PCMCIA_DEBUG | 575 | #ifdef CM4000_DEBUG |
583 | DEBUGP(2, dev, "PTSreply: "); | 576 | DEBUGP(2, dev, "PTSreply: "); |
584 | for (i = 0; i < num_bytes_read; i++) { | 577 | for (i = 0; i < num_bytes_read; i++) { |
585 | if (pc_debug >= 5) | 578 | pr_debug("0x%.2x ", pts_reply[i]); |
586 | printk("0x%.2x ", pts_reply[i]); | ||
587 | } | 579 | } |
588 | printk("\n"); | 580 | pr_debug("\n"); |
589 | #endif /* PCMCIA_DEBUG */ | 581 | #endif /* CM4000_DEBUG */ |
590 | 582 | ||
591 | DEBUGP(5, dev, "Clear Tactive in Flags1\n"); | 583 | DEBUGP(5, dev, "Clear Tactive in Flags1\n"); |
592 | xoutb(0x20, REG_FLAGS1(iobase)); | 584 | xoutb(0x20, REG_FLAGS1(iobase)); |
@@ -655,7 +647,7 @@ static void terminate_monitor(struct cm4000_dev *dev) | |||
655 | 647 | ||
656 | DEBUGP(5, dev, "Delete timer\n"); | 648 | DEBUGP(5, dev, "Delete timer\n"); |
657 | del_timer_sync(&dev->timer); | 649 | del_timer_sync(&dev->timer); |
658 | #ifdef PCMCIA_DEBUG | 650 | #ifdef CM4000_DEBUG |
659 | dev->monitor_running = 0; | 651 | dev->monitor_running = 0; |
660 | #endif | 652 | #endif |
661 | 653 | ||
@@ -898,7 +890,7 @@ static void monitor_card(unsigned long p) | |||
898 | DEBUGP(4, dev, "ATR checksum (0x%.2x, should " | 890 | DEBUGP(4, dev, "ATR checksum (0x%.2x, should " |
899 | "be zero) failed\n", dev->atr_csum); | 891 | "be zero) failed\n", dev->atr_csum); |
900 | } | 892 | } |
901 | #ifdef PCMCIA_DEBUG | 893 | #ifdef CM4000_DEBUG |
902 | else if (test_bit(IS_BAD_LENGTH, &dev->flags)) { | 894 | else if (test_bit(IS_BAD_LENGTH, &dev->flags)) { |
903 | DEBUGP(4, dev, "ATR length error\n"); | 895 | DEBUGP(4, dev, "ATR length error\n"); |
904 | } else { | 896 | } else { |
@@ -1415,7 +1407,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1415 | int size; | 1407 | int size; |
1416 | int rc; | 1408 | int rc; |
1417 | void __user *argp = (void __user *)arg; | 1409 | void __user *argp = (void __user *)arg; |
1418 | #ifdef PCMCIA_DEBUG | 1410 | #ifdef CM4000_DEBUG |
1419 | char *ioctl_names[CM_IOC_MAXNR + 1] = { | 1411 | char *ioctl_names[CM_IOC_MAXNR + 1] = { |
1420 | [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS", | 1412 | [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS", |
1421 | [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR", | 1413 | [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR", |
@@ -1423,9 +1415,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1423 | [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS", | 1415 | [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS", |
1424 | [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL", | 1416 | [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL", |
1425 | }; | 1417 | }; |
1426 | #endif | ||
1427 | DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode), | 1418 | DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode), |
1428 | iminor(inode), ioctl_names[_IOC_NR(cmd)]); | 1419 | iminor(inode), ioctl_names[_IOC_NR(cmd)]); |
1420 | #endif | ||
1429 | 1421 | ||
1430 | lock_kernel(); | 1422 | lock_kernel(); |
1431 | rc = -ENODEV; | 1423 | rc = -ENODEV; |
@@ -1523,7 +1515,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1523 | } | 1515 | } |
1524 | case CM_IOCARDOFF: | 1516 | case CM_IOCARDOFF: |
1525 | 1517 | ||
1526 | #ifdef PCMCIA_DEBUG | 1518 | #ifdef CM4000_DEBUG |
1527 | DEBUGP(4, dev, "... in CM_IOCARDOFF\n"); | 1519 | DEBUGP(4, dev, "... in CM_IOCARDOFF\n"); |
1528 | if (dev->flags0 & 0x01) { | 1520 | if (dev->flags0 & 0x01) { |
1529 | DEBUGP(4, dev, " Card inserted\n"); | 1521 | DEBUGP(4, dev, " Card inserted\n"); |
@@ -1625,18 +1617,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1625 | 1617 | ||
1626 | } | 1618 | } |
1627 | break; | 1619 | break; |
1628 | #ifdef PCMCIA_DEBUG | 1620 | #ifdef CM4000_DEBUG |
1629 | case CM_IOSDBGLVL: /* set debug log level */ | 1621 | case CM_IOSDBGLVL: |
1630 | { | 1622 | rc = -ENOTTY; |
1631 | int old_pc_debug = 0; | ||
1632 | |||
1633 | old_pc_debug = pc_debug; | ||
1634 | if (copy_from_user(&pc_debug, argp, sizeof(int))) | ||
1635 | rc = -EFAULT; | ||
1636 | else if (old_pc_debug != pc_debug) | ||
1637 | DEBUGP(0, dev, "Changed debug log level " | ||
1638 | "to %i\n", pc_debug); | ||
1639 | } | ||
1640 | break; | 1623 | break; |
1641 | #endif | 1624 | #endif |
1642 | default: | 1625 | default: |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 4f0723b07974..a6a70e476bea 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -17,8 +17,6 @@ | |||
17 | * All rights reserved, Dual BSD/GPL Licensed. | 17 | * All rights reserved, Dual BSD/GPL Licensed. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* #define PCMCIA_DEBUG 6 */ | ||
21 | |||
22 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 21 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -41,18 +39,16 @@ | |||
41 | #include "cm4040_cs.h" | 39 | #include "cm4040_cs.h" |
42 | 40 | ||
43 | 41 | ||
44 | #ifdef PCMCIA_DEBUG | 42 | #define reader_to_dev(x) (&x->p_dev->dev) |
45 | #define reader_to_dev(x) (&handle_to_dev(x->p_dev)) | 43 | |
46 | static int pc_debug = PCMCIA_DEBUG; | 44 | /* n (debug level) is ignored */ |
47 | module_param(pc_debug, int, 0600); | 45 | /* additional debug output may be enabled by re-compiling with |
48 | #define DEBUGP(n, rdr, x, args...) do { \ | 46 | * CM4040_DEBUG set */ |
49 | if (pc_debug >= (n)) \ | 47 | /* #define CM4040_DEBUG */ |
50 | dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \ | 48 | #define DEBUGP(n, rdr, x, args...) do { \ |
51 | __func__ , ##args); \ | 49 | dev_dbg(reader_to_dev(rdr), "%s:" x, \ |
50 | __func__ , ## args); \ | ||
52 | } while (0) | 51 | } while (0) |
53 | #else | ||
54 | #define DEBUGP(n, rdr, x, args...) | ||
55 | #endif | ||
56 | 52 | ||
57 | static char *version = | 53 | static char *version = |
58 | "OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte"; | 54 | "OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte"; |
@@ -90,14 +86,13 @@ struct reader_dev { | |||
90 | 86 | ||
91 | static struct pcmcia_device *dev_table[CM_MAX_DEV]; | 87 | static struct pcmcia_device *dev_table[CM_MAX_DEV]; |
92 | 88 | ||
93 | #ifndef PCMCIA_DEBUG | 89 | #ifndef CM4040_DEBUG |
94 | #define xoutb outb | 90 | #define xoutb outb |
95 | #define xinb inb | 91 | #define xinb inb |
96 | #else | 92 | #else |
97 | static inline void xoutb(unsigned char val, unsigned short port) | 93 | static inline void xoutb(unsigned char val, unsigned short port) |
98 | { | 94 | { |
99 | if (pc_debug >= 7) | 95 | pr_debug("outb(val=%.2x,port=%.4x)\n", val, port); |
100 | printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port); | ||
101 | outb(val, port); | 96 | outb(val, port); |
102 | } | 97 | } |
103 | 98 | ||
@@ -106,8 +101,7 @@ static inline unsigned char xinb(unsigned short port) | |||
106 | unsigned char val; | 101 | unsigned char val; |
107 | 102 | ||
108 | val = inb(port); | 103 | val = inb(port); |
109 | if (pc_debug >= 7) | 104 | pr_debug("%.2x=inb(%.4x)\n", val, port); |
110 | printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port); | ||
111 | return val; | 105 | return val; |
112 | } | 106 | } |
113 | #endif | 107 | #endif |
@@ -260,23 +254,22 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, | |||
260 | return -EIO; | 254 | return -EIO; |
261 | } | 255 | } |
262 | dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN); | 256 | dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN); |
263 | #ifdef PCMCIA_DEBUG | 257 | #ifdef CM4040_DEBUG |
264 | if (pc_debug >= 6) | 258 | pr_debug("%lu:%2x ", i, dev->r_buf[i]); |
265 | printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); | ||
266 | } | 259 | } |
267 | printk("\n"); | 260 | pr_debug("\n"); |
268 | #else | 261 | #else |
269 | } | 262 | } |
270 | #endif | 263 | #endif |
271 | 264 | ||
272 | bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]); | 265 | bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]); |
273 | 266 | ||
274 | DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read); | 267 | DEBUGP(6, dev, "BytesToRead=%zu\n", bytes_to_read); |
275 | 268 | ||
276 | min_bytes_to_read = min(count, bytes_to_read + 5); | 269 | min_bytes_to_read = min(count, bytes_to_read + 5); |
277 | min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE); | 270 | min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE); |
278 | 271 | ||
279 | DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read); | 272 | DEBUGP(6, dev, "Min=%zu\n", min_bytes_to_read); |
280 | 273 | ||
281 | for (i = 0; i < (min_bytes_to_read-5); i++) { | 274 | for (i = 0; i < (min_bytes_to_read-5); i++) { |
282 | rc = wait_for_bulk_in_ready(dev); | 275 | rc = wait_for_bulk_in_ready(dev); |
@@ -288,11 +281,10 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf, | |||
288 | return -EIO; | 281 | return -EIO; |
289 | } | 282 | } |
290 | dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN); | 283 | dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN); |
291 | #ifdef PCMCIA_DEBUG | 284 | #ifdef CM4040_DEBUG |
292 | if (pc_debug >= 6) | 285 | pr_debug("%lu:%2x ", i, dev->r_buf[i]); |
293 | printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]); | ||
294 | } | 286 | } |
295 | printk("\n"); | 287 | pr_debug("\n"); |
296 | #else | 288 | #else |
297 | } | 289 | } |
298 | #endif | 290 | #endif |
@@ -547,7 +539,7 @@ static int cm4040_config_check(struct pcmcia_device *p_dev, | |||
547 | p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; | 539 | p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; |
548 | 540 | ||
549 | rc = pcmcia_request_io(p_dev, &p_dev->io); | 541 | rc = pcmcia_request_io(p_dev, &p_dev->io); |
550 | dev_printk(KERN_INFO, &handle_to_dev(p_dev), | 542 | dev_printk(KERN_INFO, &p_dev->dev, |
551 | "pcmcia_request_io returned 0x%x\n", rc); | 543 | "pcmcia_request_io returned 0x%x\n", rc); |
552 | return rc; | 544 | return rc; |
553 | } | 545 | } |
@@ -569,7 +561,7 @@ static int reader_config(struct pcmcia_device *link, int devno) | |||
569 | 561 | ||
570 | fail_rc = pcmcia_request_configuration(link, &link->conf); | 562 | fail_rc = pcmcia_request_configuration(link, &link->conf); |
571 | if (fail_rc != 0) { | 563 | if (fail_rc != 0) { |
572 | dev_printk(KERN_INFO, &handle_to_dev(link), | 564 | dev_printk(KERN_INFO, &link->dev, |
573 | "pcmcia_request_configuration failed 0x%x\n", | 565 | "pcmcia_request_configuration failed 0x%x\n", |
574 | fail_rc); | 566 | fail_rc); |
575 | goto cs_release; | 567 | goto cs_release; |
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c index 4c1820cad712..99cffdab1056 100644 --- a/drivers/char/pcmcia/ipwireless/hardware.c +++ b/drivers/char/pcmcia/ipwireless/hardware.c | |||
@@ -1213,12 +1213,12 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, | |||
1213 | 1213 | ||
1214 | irqreturn_t ipwireless_interrupt(int irq, void *dev_id) | 1214 | irqreturn_t ipwireless_interrupt(int irq, void *dev_id) |
1215 | { | 1215 | { |
1216 | struct ipw_hardware *hw = dev_id; | 1216 | struct ipw_dev *ipw = dev_id; |
1217 | 1217 | ||
1218 | if (hw->hw_version == HW_VERSION_1) | 1218 | if (ipw->hardware->hw_version == HW_VERSION_1) |
1219 | return ipwireless_handle_v1_interrupt(irq, hw); | 1219 | return ipwireless_handle_v1_interrupt(irq, ipw->hardware); |
1220 | else | 1220 | else |
1221 | return ipwireless_handle_v2_v3_interrupt(irq, hw); | 1221 | return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware); |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | static void flush_packets_to_hw(struct ipw_hardware *hw) | 1224 | static void flush_packets_to_hw(struct ipw_hardware *hw) |
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c index 5216fce0c62d..dff24dae1485 100644 --- a/drivers/char/pcmcia/ipwireless/main.c +++ b/drivers/char/pcmcia/ipwireless/main.c | |||
@@ -65,10 +65,7 @@ static void signalled_reboot_work(struct work_struct *work_reboot) | |||
65 | struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, | 65 | struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev, |
66 | work_reboot); | 66 | work_reboot); |
67 | struct pcmcia_device *link = ipw->link; | 67 | struct pcmcia_device *link = ipw->link; |
68 | int ret = pcmcia_reset_card(link->socket); | 68 | pcmcia_reset_card(link->socket); |
69 | |||
70 | if (ret != 0) | ||
71 | cs_error(link, ResetCard, ret); | ||
72 | } | 69 | } |
73 | 70 | ||
74 | static void signalled_reboot_callback(void *callback_data) | 71 | static void signalled_reboot_callback(void *callback_data) |
@@ -79,208 +76,127 @@ static void signalled_reboot_callback(void *callback_data) | |||
79 | schedule_work(&ipw->work_reboot); | 76 | schedule_work(&ipw->work_reboot); |
80 | } | 77 | } |
81 | 78 | ||
82 | static int config_ipwireless(struct ipw_dev *ipw) | 79 | static int ipwireless_probe(struct pcmcia_device *p_dev, |
80 | cistpl_cftable_entry_t *cfg, | ||
81 | cistpl_cftable_entry_t *dflt, | ||
82 | unsigned int vcc, | ||
83 | void *priv_data) | ||
83 | { | 84 | { |
84 | struct pcmcia_device *link = ipw->link; | 85 | struct ipw_dev *ipw = priv_data; |
85 | int ret; | 86 | struct resource *io_resource; |
86 | tuple_t tuple; | ||
87 | unsigned short buf[64]; | ||
88 | cisparse_t parse; | ||
89 | unsigned short cor_value; | ||
90 | memreq_t memreq_attr_memory; | 87 | memreq_t memreq_attr_memory; |
91 | memreq_t memreq_common_memory; | 88 | memreq_t memreq_common_memory; |
89 | int ret; | ||
92 | 90 | ||
93 | ipw->is_v2_card = 0; | 91 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
94 | 92 | p_dev->io.BasePort1 = cfg->io.win[0].base; | |
95 | tuple.Attributes = 0; | 93 | p_dev->io.NumPorts1 = cfg->io.win[0].len; |
96 | tuple.TupleData = (cisdata_t *) buf; | 94 | p_dev->io.IOAddrLines = 16; |
97 | tuple.TupleDataMax = sizeof(buf); | ||
98 | tuple.TupleOffset = 0; | ||
99 | |||
100 | tuple.DesiredTuple = RETURN_FIRST_TUPLE; | ||
101 | |||
102 | ret = pcmcia_get_first_tuple(link, &tuple); | ||
103 | |||
104 | while (ret == 0) { | ||
105 | ret = pcmcia_get_tuple_data(link, &tuple); | ||
106 | |||
107 | if (ret != 0) { | ||
108 | cs_error(link, GetTupleData, ret); | ||
109 | goto exit0; | ||
110 | } | ||
111 | ret = pcmcia_get_next_tuple(link, &tuple); | ||
112 | } | ||
113 | |||
114 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
115 | |||
116 | ret = pcmcia_get_first_tuple(link, &tuple); | ||
117 | |||
118 | if (ret != 0) { | ||
119 | cs_error(link, GetFirstTuple, ret); | ||
120 | goto exit0; | ||
121 | } | ||
122 | |||
123 | ret = pcmcia_get_tuple_data(link, &tuple); | ||
124 | |||
125 | if (ret != 0) { | ||
126 | cs_error(link, GetTupleData, ret); | ||
127 | goto exit0; | ||
128 | } | ||
129 | |||
130 | ret = pcmcia_parse_tuple(&tuple, &parse); | ||
131 | |||
132 | if (ret != 0) { | ||
133 | cs_error(link, ParseTuple, ret); | ||
134 | goto exit0; | ||
135 | } | ||
136 | |||
137 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
138 | link->io.BasePort1 = parse.cftable_entry.io.win[0].base; | ||
139 | link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; | ||
140 | link->io.IOAddrLines = 16; | ||
141 | |||
142 | link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1; | ||
143 | 95 | ||
144 | /* 0x40 causes it to generate level mode interrupts. */ | 96 | /* 0x40 causes it to generate level mode interrupts. */ |
145 | /* 0x04 enables IREQ pin. */ | 97 | /* 0x04 enables IREQ pin. */ |
146 | cor_value = parse.cftable_entry.index | 0x44; | 98 | p_dev->conf.ConfigIndex = cfg->index | 0x44; |
147 | link->conf.ConfigIndex = cor_value; | 99 | ret = pcmcia_request_io(p_dev, &p_dev->io); |
100 | if (ret) | ||
101 | return ret; | ||
148 | 102 | ||
149 | /* IRQ and I/O settings */ | 103 | io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1, |
150 | tuple.DesiredTuple = CISTPL_CONFIG; | 104 | IPWIRELESS_PCCARD_NAME); |
151 | 105 | ||
152 | ret = pcmcia_get_first_tuple(link, &tuple); | 106 | if (cfg->mem.nwin == 0) |
107 | return 0; | ||
153 | 108 | ||
154 | if (ret != 0) { | 109 | ipw->request_common_memory.Attributes = |
155 | cs_error(link, GetFirstTuple, ret); | 110 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; |
156 | goto exit0; | 111 | ipw->request_common_memory.Base = cfg->mem.win[0].host_addr; |
157 | } | 112 | ipw->request_common_memory.Size = cfg->mem.win[0].len; |
113 | if (ipw->request_common_memory.Size < 0x1000) | ||
114 | ipw->request_common_memory.Size = 0x1000; | ||
115 | ipw->request_common_memory.AccessSpeed = 0; | ||
158 | 116 | ||
159 | ret = pcmcia_get_tuple_data(link, &tuple); | 117 | ret = pcmcia_request_window(p_dev, &ipw->request_common_memory, |
160 | 118 | &ipw->handle_common_memory); | |
161 | if (ret != 0) { | ||
162 | cs_error(link, GetTupleData, ret); | ||
163 | goto exit0; | ||
164 | } | ||
165 | 119 | ||
166 | ret = pcmcia_parse_tuple(&tuple, &parse); | 120 | if (ret != 0) |
121 | goto exit1; | ||
167 | 122 | ||
168 | if (ret != 0) { | 123 | memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr; |
169 | cs_error(link, GetTupleData, ret); | 124 | memreq_common_memory.Page = 0; |
170 | goto exit0; | ||
171 | } | ||
172 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
173 | link->conf.ConfigBase = parse.config.base; | ||
174 | link->conf.Present = parse.config.rmask[0]; | ||
175 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
176 | 125 | ||
177 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; | 126 | ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory, |
178 | link->irq.Handler = ipwireless_interrupt; | 127 | &memreq_common_memory); |
179 | link->irq.Instance = ipw->hardware; | ||
180 | 128 | ||
181 | ret = pcmcia_request_io(link, &link->io); | 129 | if (ret != 0) |
130 | goto exit2; | ||
182 | 131 | ||
183 | if (ret != 0) { | 132 | ipw->is_v2_card = cfg->mem.win[0].len == 0x100; |
184 | cs_error(link, RequestIO, ret); | ||
185 | goto exit0; | ||
186 | } | ||
187 | 133 | ||
188 | request_region(link->io.BasePort1, link->io.NumPorts1, | 134 | ipw->common_memory = ioremap(ipw->request_common_memory.Base, |
135 | ipw->request_common_memory.Size); | ||
136 | request_mem_region(ipw->request_common_memory.Base, | ||
137 | ipw->request_common_memory.Size, | ||
189 | IPWIRELESS_PCCARD_NAME); | 138 | IPWIRELESS_PCCARD_NAME); |
190 | 139 | ||
191 | /* memory settings */ | 140 | ipw->request_attr_memory.Attributes = |
192 | 141 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; | |
193 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 142 | ipw->request_attr_memory.Base = 0; |
194 | 143 | ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ | |
195 | ret = pcmcia_get_first_tuple(link, &tuple); | 144 | ipw->request_attr_memory.AccessSpeed = 0; |
196 | |||
197 | if (ret != 0) { | ||
198 | cs_error(link, GetFirstTuple, ret); | ||
199 | goto exit1; | ||
200 | } | ||
201 | |||
202 | ret = pcmcia_get_tuple_data(link, &tuple); | ||
203 | 145 | ||
204 | if (ret != 0) { | 146 | ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory, |
205 | cs_error(link, GetTupleData, ret); | 147 | &ipw->handle_attr_memory); |
206 | goto exit1; | ||
207 | } | ||
208 | |||
209 | ret = pcmcia_parse_tuple(&tuple, &parse); | ||
210 | |||
211 | if (ret != 0) { | ||
212 | cs_error(link, ParseTuple, ret); | ||
213 | goto exit1; | ||
214 | } | ||
215 | 148 | ||
216 | if (parse.cftable_entry.mem.nwin > 0) { | 149 | if (ret != 0) |
217 | ipw->request_common_memory.Attributes = | 150 | goto exit2; |
218 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; | ||
219 | ipw->request_common_memory.Base = | ||
220 | parse.cftable_entry.mem.win[0].host_addr; | ||
221 | ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len; | ||
222 | if (ipw->request_common_memory.Size < 0x1000) | ||
223 | ipw->request_common_memory.Size = 0x1000; | ||
224 | ipw->request_common_memory.AccessSpeed = 0; | ||
225 | |||
226 | ret = pcmcia_request_window(&link, &ipw->request_common_memory, | ||
227 | &ipw->handle_common_memory); | ||
228 | 151 | ||
229 | if (ret != 0) { | 152 | memreq_attr_memory.CardOffset = 0; |
230 | cs_error(link, RequestWindow, ret); | 153 | memreq_attr_memory.Page = 0; |
231 | goto exit1; | ||
232 | } | ||
233 | 154 | ||
234 | memreq_common_memory.CardOffset = | 155 | ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory, |
235 | parse.cftable_entry.mem.win[0].card_addr; | 156 | &memreq_attr_memory); |
236 | memreq_common_memory.Page = 0; | ||
237 | 157 | ||
238 | ret = pcmcia_map_mem_page(ipw->handle_common_memory, | 158 | if (ret != 0) |
239 | &memreq_common_memory); | 159 | goto exit3; |
240 | 160 | ||
241 | if (ret != 0) { | 161 | ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, |
242 | cs_error(link, MapMemPage, ret); | 162 | ipw->request_attr_memory.Size); |
243 | goto exit1; | 163 | request_mem_region(ipw->request_attr_memory.Base, |
244 | } | 164 | ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME); |
245 | 165 | ||
246 | ipw->is_v2_card = | 166 | return 0; |
247 | parse.cftable_entry.mem.win[0].len == 0x100; | ||
248 | 167 | ||
249 | ipw->common_memory = ioremap(ipw->request_common_memory.Base, | 168 | exit3: |
169 | pcmcia_release_window(p_dev, ipw->handle_attr_memory); | ||
170 | exit2: | ||
171 | if (ipw->common_memory) { | ||
172 | release_mem_region(ipw->request_common_memory.Base, | ||
250 | ipw->request_common_memory.Size); | 173 | ipw->request_common_memory.Size); |
251 | request_mem_region(ipw->request_common_memory.Base, | 174 | iounmap(ipw->common_memory); |
252 | ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME); | 175 | pcmcia_release_window(p_dev, ipw->handle_common_memory); |
253 | 176 | } else | |
254 | ipw->request_attr_memory.Attributes = | 177 | pcmcia_release_window(p_dev, ipw->handle_common_memory); |
255 | WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; | 178 | exit1: |
256 | ipw->request_attr_memory.Base = 0; | 179 | release_resource(io_resource); |
257 | ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ | 180 | pcmcia_disable_device(p_dev); |
258 | ipw->request_attr_memory.AccessSpeed = 0; | 181 | return -1; |
259 | 182 | } | |
260 | ret = pcmcia_request_window(&link, &ipw->request_attr_memory, | ||
261 | &ipw->handle_attr_memory); | ||
262 | 183 | ||
263 | if (ret != 0) { | 184 | static int config_ipwireless(struct ipw_dev *ipw) |
264 | cs_error(link, RequestWindow, ret); | 185 | { |
265 | goto exit2; | 186 | struct pcmcia_device *link = ipw->link; |
266 | } | 187 | int ret = 0; |
267 | 188 | ||
268 | memreq_attr_memory.CardOffset = 0; | 189 | ipw->is_v2_card = 0; |
269 | memreq_attr_memory.Page = 0; | ||
270 | 190 | ||
271 | ret = pcmcia_map_mem_page(ipw->handle_attr_memory, | 191 | ret = pcmcia_loop_config(link, ipwireless_probe, ipw); |
272 | &memreq_attr_memory); | 192 | if (ret != 0) |
193 | return ret; | ||
273 | 194 | ||
274 | if (ret != 0) { | 195 | link->conf.Attributes = CONF_ENABLE_IRQ; |
275 | cs_error(link, MapMemPage, ret); | 196 | link->conf.IntType = INT_MEMORY_AND_IO; |
276 | goto exit2; | ||
277 | } | ||
278 | 197 | ||
279 | ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, | 198 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; |
280 | ipw->request_attr_memory.Size); | 199 | link->irq.Handler = ipwireless_interrupt; |
281 | request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size, | ||
282 | IPWIRELESS_PCCARD_NAME); | ||
283 | } | ||
284 | 200 | ||
285 | INIT_WORK(&ipw->work_reboot, signalled_reboot_work); | 201 | INIT_WORK(&ipw->work_reboot, signalled_reboot_work); |
286 | 202 | ||
@@ -291,10 +207,8 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
291 | 207 | ||
292 | ret = pcmcia_request_irq(link, &link->irq); | 208 | ret = pcmcia_request_irq(link, &link->irq); |
293 | 209 | ||
294 | if (ret != 0) { | 210 | if (ret != 0) |
295 | cs_error(link, RequestIRQ, ret); | 211 | goto exit; |
296 | goto exit3; | ||
297 | } | ||
298 | 212 | ||
299 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", | 213 | printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n", |
300 | ipw->is_v2_card ? "V2/V3" : "V1"); | 214 | ipw->is_v2_card ? "V2/V3" : "V1"); |
@@ -316,12 +230,12 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
316 | 230 | ||
317 | ipw->network = ipwireless_network_create(ipw->hardware); | 231 | ipw->network = ipwireless_network_create(ipw->hardware); |
318 | if (!ipw->network) | 232 | if (!ipw->network) |
319 | goto exit3; | 233 | goto exit; |
320 | 234 | ||
321 | ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network, | 235 | ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network, |
322 | ipw->nodes); | 236 | ipw->nodes); |
323 | if (!ipw->tty) | 237 | if (!ipw->tty) |
324 | goto exit3; | 238 | goto exit; |
325 | 239 | ||
326 | ipwireless_init_hardware_v2_v3(ipw->hardware); | 240 | ipwireless_init_hardware_v2_v3(ipw->hardware); |
327 | 241 | ||
@@ -331,35 +245,27 @@ static int config_ipwireless(struct ipw_dev *ipw) | |||
331 | */ | 245 | */ |
332 | ret = pcmcia_request_configuration(link, &link->conf); | 246 | ret = pcmcia_request_configuration(link, &link->conf); |
333 | 247 | ||
334 | if (ret != 0) { | 248 | if (ret != 0) |
335 | cs_error(link, RequestConfiguration, ret); | 249 | goto exit; |
336 | goto exit4; | ||
337 | } | ||
338 | 250 | ||
339 | link->dev_node = &ipw->nodes[0]; | 251 | link->dev_node = &ipw->nodes[0]; |
340 | 252 | ||
341 | return 0; | 253 | return 0; |
342 | 254 | ||
343 | exit4: | 255 | exit: |
344 | pcmcia_disable_device(link); | ||
345 | exit3: | ||
346 | if (ipw->attr_memory) { | 256 | if (ipw->attr_memory) { |
347 | release_mem_region(ipw->request_attr_memory.Base, | 257 | release_mem_region(ipw->request_attr_memory.Base, |
348 | ipw->request_attr_memory.Size); | 258 | ipw->request_attr_memory.Size); |
349 | iounmap(ipw->attr_memory); | 259 | iounmap(ipw->attr_memory); |
350 | pcmcia_release_window(ipw->handle_attr_memory); | 260 | pcmcia_release_window(link, ipw->handle_attr_memory); |
351 | pcmcia_disable_device(link); | ||
352 | } | 261 | } |
353 | exit2: | ||
354 | if (ipw->common_memory) { | 262 | if (ipw->common_memory) { |
355 | release_mem_region(ipw->request_common_memory.Base, | 263 | release_mem_region(ipw->request_common_memory.Base, |
356 | ipw->request_common_memory.Size); | 264 | ipw->request_common_memory.Size); |
357 | iounmap(ipw->common_memory); | 265 | iounmap(ipw->common_memory); |
358 | pcmcia_release_window(ipw->handle_common_memory); | 266 | pcmcia_release_window(link, ipw->handle_common_memory); |
359 | } | 267 | } |
360 | exit1: | ||
361 | pcmcia_disable_device(link); | 268 | pcmcia_disable_device(link); |
362 | exit0: | ||
363 | return -1; | 269 | return -1; |
364 | } | 270 | } |
365 | 271 | ||
@@ -378,9 +284,9 @@ static void release_ipwireless(struct ipw_dev *ipw) | |||
378 | iounmap(ipw->attr_memory); | 284 | iounmap(ipw->attr_memory); |
379 | } | 285 | } |
380 | if (ipw->common_memory) | 286 | if (ipw->common_memory) |
381 | pcmcia_release_window(ipw->handle_common_memory); | 287 | pcmcia_release_window(ipw->link, ipw->handle_common_memory); |
382 | if (ipw->attr_memory) | 288 | if (ipw->attr_memory) |
383 | pcmcia_release_window(ipw->handle_attr_memory); | 289 | pcmcia_release_window(ipw->link, ipw->handle_attr_memory); |
384 | 290 | ||
385 | /* Break the link with Card Services */ | 291 | /* Break the link with Card Services */ |
386 | pcmcia_disable_device(ipw->link); | 292 | pcmcia_disable_device(ipw->link); |
@@ -406,7 +312,6 @@ static int ipwireless_attach(struct pcmcia_device *link) | |||
406 | 312 | ||
407 | ipw->link = link; | 313 | ipw->link = link; |
408 | link->priv = ipw; | 314 | link->priv = ipw; |
409 | link->irq.Instance = ipw; | ||
410 | 315 | ||
411 | /* Link this device into our device list. */ | 316 | /* Link this device into our device list. */ |
412 | link->dev_node = &ipw->nodes[0]; | 317 | link->dev_node = &ipw->nodes[0]; |
@@ -421,7 +326,6 @@ static int ipwireless_attach(struct pcmcia_device *link) | |||
421 | ret = config_ipwireless(ipw); | 326 | ret = config_ipwireless(ipw); |
422 | 327 | ||
423 | if (ret != 0) { | 328 | if (ret != 0) { |
424 | cs_error(link, RegisterClient, ret); | ||
425 | ipwireless_detach(link); | 329 | ipwireless_detach(link); |
426 | return ret; | 330 | return ret; |
427 | } | 331 | } |
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 674b3ab3587d..2bb7874a6899 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -603,7 +603,7 @@ void ipwireless_tty_free(struct ipw_tty *tty) | |||
603 | } | 603 | } |
604 | } | 604 | } |
605 | 605 | ||
606 | static struct tty_operations tty_ops = { | 606 | static const struct tty_operations tty_ops = { |
607 | .open = ipw_open, | 607 | .open = ipw_open, |
608 | .close = ipw_close, | 608 | .close = ipw_close, |
609 | .hangup = ipw_hangup, | 609 | .hangup = ipw_hangup, |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index caf6e4d19469..c31a0d913d37 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -554,7 +554,6 @@ static int mgslpc_probe(struct pcmcia_device *link) | |||
554 | 554 | ||
555 | /* Interrupt setup */ | 555 | /* Interrupt setup */ |
556 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; | 556 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; |
557 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | ||
558 | link->irq.Handler = NULL; | 557 | link->irq.Handler = NULL; |
559 | 558 | ||
560 | link->conf.Attributes = 0; | 559 | link->conf.Attributes = 0; |
@@ -572,69 +571,51 @@ static int mgslpc_probe(struct pcmcia_device *link) | |||
572 | /* Card has been inserted. | 571 | /* Card has been inserted. |
573 | */ | 572 | */ |
574 | 573 | ||
575 | #define CS_CHECK(fn, ret) \ | 574 | static int mgslpc_ioprobe(struct pcmcia_device *p_dev, |
576 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 575 | cistpl_cftable_entry_t *cfg, |
576 | cistpl_cftable_entry_t *dflt, | ||
577 | unsigned int vcc, | ||
578 | void *priv_data) | ||
579 | { | ||
580 | if (cfg->io.nwin > 0) { | ||
581 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
582 | if (!(cfg->io.flags & CISTPL_IO_8BIT)) | ||
583 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
584 | if (!(cfg->io.flags & CISTPL_IO_16BIT)) | ||
585 | p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
586 | p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK; | ||
587 | p_dev->io.BasePort1 = cfg->io.win[0].base; | ||
588 | p_dev->io.NumPorts1 = cfg->io.win[0].len; | ||
589 | return pcmcia_request_io(p_dev, &p_dev->io); | ||
590 | } | ||
591 | return -ENODEV; | ||
592 | } | ||
577 | 593 | ||
578 | static int mgslpc_config(struct pcmcia_device *link) | 594 | static int mgslpc_config(struct pcmcia_device *link) |
579 | { | 595 | { |
580 | MGSLPC_INFO *info = link->priv; | 596 | MGSLPC_INFO *info = link->priv; |
581 | tuple_t tuple; | 597 | int ret; |
582 | cisparse_t parse; | ||
583 | int last_fn, last_ret; | ||
584 | u_char buf[64]; | ||
585 | cistpl_cftable_entry_t dflt = { 0 }; | ||
586 | cistpl_cftable_entry_t *cfg; | ||
587 | 598 | ||
588 | if (debug_level >= DEBUG_LEVEL_INFO) | 599 | if (debug_level >= DEBUG_LEVEL_INFO) |
589 | printk("mgslpc_config(0x%p)\n", link); | 600 | printk("mgslpc_config(0x%p)\n", link); |
590 | 601 | ||
591 | tuple.Attributes = 0; | 602 | ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL); |
592 | tuple.TupleData = buf; | 603 | if (ret != 0) |
593 | tuple.TupleDataMax = sizeof(buf); | 604 | goto failed; |
594 | tuple.TupleOffset = 0; | ||
595 | |||
596 | /* get CIS configuration entry */ | ||
597 | |||
598 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
599 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
600 | |||
601 | cfg = &(parse.cftable_entry); | ||
602 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
603 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse)); | ||
604 | |||
605 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; | ||
606 | if (cfg->index == 0) | ||
607 | goto cs_failed; | ||
608 | |||
609 | link->conf.ConfigIndex = cfg->index; | ||
610 | link->conf.Attributes |= CONF_ENABLE_IRQ; | ||
611 | |||
612 | /* IO window settings */ | ||
613 | link->io.NumPorts1 = 0; | ||
614 | if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | ||
615 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | ||
616 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
617 | if (!(io->flags & CISTPL_IO_8BIT)) | ||
618 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; | ||
619 | if (!(io->flags & CISTPL_IO_16BIT)) | ||
620 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
621 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
622 | link->io.BasePort1 = io->win[0].base; | ||
623 | link->io.NumPorts1 = io->win[0].len; | ||
624 | CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); | ||
625 | } | ||
626 | 605 | ||
627 | link->conf.Attributes = CONF_ENABLE_IRQ; | 606 | link->conf.Attributes = CONF_ENABLE_IRQ; |
628 | link->conf.IntType = INT_MEMORY_AND_IO; | 607 | link->conf.IntType = INT_MEMORY_AND_IO; |
629 | link->conf.ConfigIndex = 8; | 608 | link->conf.ConfigIndex = 8; |
630 | link->conf.Present = PRESENT_OPTION; | 609 | link->conf.Present = PRESENT_OPTION; |
631 | 610 | ||
632 | link->irq.Attributes |= IRQ_HANDLE_PRESENT; | ||
633 | link->irq.Handler = mgslpc_isr; | 611 | link->irq.Handler = mgslpc_isr; |
634 | link->irq.Instance = info; | ||
635 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); | ||
636 | 612 | ||
637 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); | 613 | ret = pcmcia_request_irq(link, &link->irq); |
614 | if (ret) | ||
615 | goto failed; | ||
616 | ret = pcmcia_request_configuration(link, &link->conf); | ||
617 | if (ret) | ||
618 | goto failed; | ||
638 | 619 | ||
639 | info->io_base = link->io.BasePort1; | 620 | info->io_base = link->io.BasePort1; |
640 | info->irq_level = link->irq.AssignedIRQ; | 621 | info->irq_level = link->irq.AssignedIRQ; |
@@ -654,8 +635,7 @@ static int mgslpc_config(struct pcmcia_device *link) | |||
654 | printk("\n"); | 635 | printk("\n"); |
655 | return 0; | 636 | return 0; |
656 | 637 | ||
657 | cs_failed: | 638 | failed: |
658 | cs_error(link, last_fn, last_ret); | ||
659 | mgslpc_release((u_long)link); | 639 | mgslpc_release((u_long)link); |
660 | return -ENODEV; | 640 | return -ENODEV; |
661 | } | 641 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 62f282e67638..385c44b3034f 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -431,30 +431,25 @@ static struct cdev ptmx_cdev; | |||
431 | 431 | ||
432 | static struct ctl_table pty_table[] = { | 432 | static struct ctl_table pty_table[] = { |
433 | { | 433 | { |
434 | .ctl_name = PTY_MAX, | ||
435 | .procname = "max", | 434 | .procname = "max", |
436 | .maxlen = sizeof(int), | 435 | .maxlen = sizeof(int), |
437 | .mode = 0644, | 436 | .mode = 0644, |
438 | .data = &pty_limit, | 437 | .data = &pty_limit, |
439 | .proc_handler = &proc_dointvec_minmax, | 438 | .proc_handler = proc_dointvec_minmax, |
440 | .strategy = &sysctl_intvec, | ||
441 | .extra1 = &pty_limit_min, | 439 | .extra1 = &pty_limit_min, |
442 | .extra2 = &pty_limit_max, | 440 | .extra2 = &pty_limit_max, |
443 | }, { | 441 | }, { |
444 | .ctl_name = PTY_NR, | ||
445 | .procname = "nr", | 442 | .procname = "nr", |
446 | .maxlen = sizeof(int), | 443 | .maxlen = sizeof(int), |
447 | .mode = 0444, | 444 | .mode = 0444, |
448 | .data = &pty_count, | 445 | .data = &pty_count, |
449 | .proc_handler = &proc_dointvec, | 446 | .proc_handler = proc_dointvec, |
450 | }, { | 447 | }, |
451 | .ctl_name = 0 | 448 | {} |
452 | } | ||
453 | }; | 449 | }; |
454 | 450 | ||
455 | static struct ctl_table pty_kern_table[] = { | 451 | static struct ctl_table pty_kern_table[] = { |
456 | { | 452 | { |
457 | .ctl_name = KERN_PTY, | ||
458 | .procname = "pty", | 453 | .procname = "pty", |
459 | .mode = 0555, | 454 | .mode = 0555, |
460 | .child = pty_table, | 455 | .child = pty_table, |
@@ -464,7 +459,6 @@ static struct ctl_table pty_kern_table[] = { | |||
464 | 459 | ||
465 | static struct ctl_table pty_root_table[] = { | 460 | static struct ctl_table pty_root_table[] = { |
466 | { | 461 | { |
467 | .ctl_name = CTL_KERN, | ||
468 | .procname = "kernel", | 462 | .procname = "kernel", |
469 | .mode = 0555, | 463 | .mode = 0555, |
470 | .child = pty_kern_table, | 464 | .child = pty_kern_table, |
@@ -665,7 +659,7 @@ static int __ptmx_open(struct inode *inode, struct file *filp) | |||
665 | if (!retval) | 659 | if (!retval) |
666 | return 0; | 660 | return 0; |
667 | out1: | 661 | out1: |
668 | tty_release_dev(filp); | 662 | tty_release(inode, filp); |
669 | return retval; | 663 | return retval; |
670 | out: | 664 | out: |
671 | devpts_kill_index(inode, index); | 665 | devpts_kill_index(inode, index); |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 04b505e5a5e2..8258982b49ec 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1245,112 +1245,68 @@ static int proc_do_uuid(ctl_table *table, int write, | |||
1245 | if (uuid[8] == 0) | 1245 | if (uuid[8] == 0) |
1246 | generate_random_uuid(uuid); | 1246 | generate_random_uuid(uuid); |
1247 | 1247 | ||
1248 | sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" | 1248 | sprintf(buf, "%pU", uuid); |
1249 | "%02x%02x%02x%02x%02x%02x", | 1249 | |
1250 | uuid[0], uuid[1], uuid[2], uuid[3], | ||
1251 | uuid[4], uuid[5], uuid[6], uuid[7], | ||
1252 | uuid[8], uuid[9], uuid[10], uuid[11], | ||
1253 | uuid[12], uuid[13], uuid[14], uuid[15]); | ||
1254 | fake_table.data = buf; | 1250 | fake_table.data = buf; |
1255 | fake_table.maxlen = sizeof(buf); | 1251 | fake_table.maxlen = sizeof(buf); |
1256 | 1252 | ||
1257 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); | 1253 | return proc_dostring(&fake_table, write, buffer, lenp, ppos); |
1258 | } | 1254 | } |
1259 | 1255 | ||
1260 | static int uuid_strategy(ctl_table *table, | ||
1261 | void __user *oldval, size_t __user *oldlenp, | ||
1262 | void __user *newval, size_t newlen) | ||
1263 | { | ||
1264 | unsigned char tmp_uuid[16], *uuid; | ||
1265 | unsigned int len; | ||
1266 | |||
1267 | if (!oldval || !oldlenp) | ||
1268 | return 1; | ||
1269 | |||
1270 | uuid = table->data; | ||
1271 | if (!uuid) { | ||
1272 | uuid = tmp_uuid; | ||
1273 | uuid[8] = 0; | ||
1274 | } | ||
1275 | if (uuid[8] == 0) | ||
1276 | generate_random_uuid(uuid); | ||
1277 | |||
1278 | if (get_user(len, oldlenp)) | ||
1279 | return -EFAULT; | ||
1280 | if (len) { | ||
1281 | if (len > 16) | ||
1282 | len = 16; | ||
1283 | if (copy_to_user(oldval, uuid, len) || | ||
1284 | put_user(len, oldlenp)) | ||
1285 | return -EFAULT; | ||
1286 | } | ||
1287 | return 1; | ||
1288 | } | ||
1289 | |||
1290 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; | 1256 | static int sysctl_poolsize = INPUT_POOL_WORDS * 32; |
1291 | ctl_table random_table[] = { | 1257 | ctl_table random_table[] = { |
1292 | { | 1258 | { |
1293 | .ctl_name = RANDOM_POOLSIZE, | ||
1294 | .procname = "poolsize", | 1259 | .procname = "poolsize", |
1295 | .data = &sysctl_poolsize, | 1260 | .data = &sysctl_poolsize, |
1296 | .maxlen = sizeof(int), | 1261 | .maxlen = sizeof(int), |
1297 | .mode = 0444, | 1262 | .mode = 0444, |
1298 | .proc_handler = &proc_dointvec, | 1263 | .proc_handler = proc_dointvec, |
1299 | }, | 1264 | }, |
1300 | { | 1265 | { |
1301 | .ctl_name = RANDOM_ENTROPY_COUNT, | ||
1302 | .procname = "entropy_avail", | 1266 | .procname = "entropy_avail", |
1303 | .maxlen = sizeof(int), | 1267 | .maxlen = sizeof(int), |
1304 | .mode = 0444, | 1268 | .mode = 0444, |
1305 | .proc_handler = &proc_dointvec, | 1269 | .proc_handler = proc_dointvec, |
1306 | .data = &input_pool.entropy_count, | 1270 | .data = &input_pool.entropy_count, |
1307 | }, | 1271 | }, |
1308 | { | 1272 | { |
1309 | .ctl_name = RANDOM_READ_THRESH, | ||
1310 | .procname = "read_wakeup_threshold", | 1273 | .procname = "read_wakeup_threshold", |
1311 | .data = &random_read_wakeup_thresh, | 1274 | .data = &random_read_wakeup_thresh, |
1312 | .maxlen = sizeof(int), | 1275 | .maxlen = sizeof(int), |
1313 | .mode = 0644, | 1276 | .mode = 0644, |
1314 | .proc_handler = &proc_dointvec_minmax, | 1277 | .proc_handler = proc_dointvec_minmax, |
1315 | .strategy = &sysctl_intvec, | ||
1316 | .extra1 = &min_read_thresh, | 1278 | .extra1 = &min_read_thresh, |
1317 | .extra2 = &max_read_thresh, | 1279 | .extra2 = &max_read_thresh, |
1318 | }, | 1280 | }, |
1319 | { | 1281 | { |
1320 | .ctl_name = RANDOM_WRITE_THRESH, | ||
1321 | .procname = "write_wakeup_threshold", | 1282 | .procname = "write_wakeup_threshold", |
1322 | .data = &random_write_wakeup_thresh, | 1283 | .data = &random_write_wakeup_thresh, |
1323 | .maxlen = sizeof(int), | 1284 | .maxlen = sizeof(int), |
1324 | .mode = 0644, | 1285 | .mode = 0644, |
1325 | .proc_handler = &proc_dointvec_minmax, | 1286 | .proc_handler = proc_dointvec_minmax, |
1326 | .strategy = &sysctl_intvec, | ||
1327 | .extra1 = &min_write_thresh, | 1287 | .extra1 = &min_write_thresh, |
1328 | .extra2 = &max_write_thresh, | 1288 | .extra2 = &max_write_thresh, |
1329 | }, | 1289 | }, |
1330 | { | 1290 | { |
1331 | .ctl_name = RANDOM_BOOT_ID, | ||
1332 | .procname = "boot_id", | 1291 | .procname = "boot_id", |
1333 | .data = &sysctl_bootid, | 1292 | .data = &sysctl_bootid, |
1334 | .maxlen = 16, | 1293 | .maxlen = 16, |
1335 | .mode = 0444, | 1294 | .mode = 0444, |
1336 | .proc_handler = &proc_do_uuid, | 1295 | .proc_handler = proc_do_uuid, |
1337 | .strategy = &uuid_strategy, | ||
1338 | }, | 1296 | }, |
1339 | { | 1297 | { |
1340 | .ctl_name = RANDOM_UUID, | ||
1341 | .procname = "uuid", | 1298 | .procname = "uuid", |
1342 | .maxlen = 16, | 1299 | .maxlen = 16, |
1343 | .mode = 0444, | 1300 | .mode = 0444, |
1344 | .proc_handler = &proc_do_uuid, | 1301 | .proc_handler = proc_do_uuid, |
1345 | .strategy = &uuid_strategy, | ||
1346 | }, | 1302 | }, |
1347 | { .ctl_name = 0 } | 1303 | { } |
1348 | }; | 1304 | }; |
1349 | #endif /* CONFIG_SYSCTL */ | 1305 | #endif /* CONFIG_SYSCTL */ |
1350 | 1306 | ||
1351 | /******************************************************************** | 1307 | /******************************************************************** |
1352 | * | 1308 | * |
1353 | * Random funtions for networking | 1309 | * Random functions for networking |
1354 | * | 1310 | * |
1355 | ********************************************************************/ | 1311 | ********************************************************************/ |
1356 | 1312 | ||
diff --git a/drivers/char/rio/route.h b/drivers/char/rio/route.h index 20ed73f3fd7b..46e963771c30 100644 --- a/drivers/char/rio/route.h +++ b/drivers/char/rio/route.h | |||
@@ -67,7 +67,7 @@ | |||
67 | typedef struct COST_ROUTE COST_ROUTE; | 67 | typedef struct COST_ROUTE COST_ROUTE; |
68 | struct COST_ROUTE { | 68 | struct COST_ROUTE { |
69 | unsigned char cost; /* Cost down this link */ | 69 | unsigned char cost; /* Cost down this link */ |
70 | unsigned char route[NODE_BYTES]; /* Nodes thorough this route */ | 70 | unsigned char route[NODE_BYTES]; /* Nodes through this route */ |
71 | }; | 71 | }; |
72 | 72 | ||
73 | typedef struct ROUTE_STR ROUTE_STR; | 73 | typedef struct ROUTE_STR ROUTE_STR; |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 3cfa22d469e0..0a8d1e56c993 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -793,26 +793,21 @@ static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp, | |||
793 | } | 793 | } |
794 | 794 | ||
795 | /* Must be called with interrupts enabled */ | 795 | /* Must be called with interrupts enabled */ |
796 | static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp, | 796 | static int rc_activate_port(struct tty_port *port, struct tty_struct *tty) |
797 | struct riscom_port *port) | ||
798 | { | 797 | { |
798 | struct riscom_port *rp = container_of(port, struct riscom_port, port); | ||
799 | struct riscom_board *bp = port_Board(rp); | ||
799 | unsigned long flags; | 800 | unsigned long flags; |
800 | 801 | ||
801 | if (port->port.flags & ASYNC_INITIALIZED) | 802 | if (tty_port_alloc_xmit_buf(port) < 0) |
802 | return 0; | ||
803 | |||
804 | if (tty_port_alloc_xmit_buf(&port->port) < 0) | ||
805 | return -ENOMEM; | 803 | return -ENOMEM; |
806 | 804 | ||
807 | spin_lock_irqsave(&riscom_lock, flags); | 805 | spin_lock_irqsave(&riscom_lock, flags); |
808 | 806 | ||
809 | clear_bit(TTY_IO_ERROR, &tty->flags); | 807 | clear_bit(TTY_IO_ERROR, &tty->flags); |
810 | if (port->port.count == 1) | 808 | bp->count++; |
811 | bp->count++; | 809 | rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0; |
812 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 810 | rc_change_speed(tty, bp, rp); |
813 | rc_change_speed(tty, bp, port); | ||
814 | port->port.flags |= ASYNC_INITIALIZED; | ||
815 | |||
816 | spin_unlock_irqrestore(&riscom_lock, flags); | 811 | spin_unlock_irqrestore(&riscom_lock, flags); |
817 | return 0; | 812 | return 0; |
818 | } | 813 | } |
@@ -821,9 +816,6 @@ static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp, | |||
821 | static void rc_shutdown_port(struct tty_struct *tty, | 816 | static void rc_shutdown_port(struct tty_struct *tty, |
822 | struct riscom_board *bp, struct riscom_port *port) | 817 | struct riscom_board *bp, struct riscom_port *port) |
823 | { | 818 | { |
824 | if (!(port->port.flags & ASYNC_INITIALIZED)) | ||
825 | return; | ||
826 | |||
827 | #ifdef RC_REPORT_OVERRUN | 819 | #ifdef RC_REPORT_OVERRUN |
828 | printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", | 820 | printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", |
829 | board_No(bp), port_No(port), port->overrun); | 821 | board_No(bp), port_No(port), port->overrun); |
@@ -840,11 +832,6 @@ static void rc_shutdown_port(struct tty_struct *tty, | |||
840 | } | 832 | } |
841 | #endif | 833 | #endif |
842 | tty_port_free_xmit_buf(&port->port); | 834 | tty_port_free_xmit_buf(&port->port); |
843 | if (C_HUPCL(tty)) { | ||
844 | /* Drop DTR */ | ||
845 | bp->DTR |= (1u << port_No(port)); | ||
846 | rc_out(bp, RC_DTR, bp->DTR); | ||
847 | } | ||
848 | 835 | ||
849 | /* Select port */ | 836 | /* Select port */ |
850 | rc_out(bp, CD180_CAR, port_No(port)); | 837 | rc_out(bp, CD180_CAR, port_No(port)); |
@@ -856,7 +843,6 @@ static void rc_shutdown_port(struct tty_struct *tty, | |||
856 | rc_out(bp, CD180_IER, port->IER); | 843 | rc_out(bp, CD180_IER, port->IER); |
857 | 844 | ||
858 | set_bit(TTY_IO_ERROR, &tty->flags); | 845 | set_bit(TTY_IO_ERROR, &tty->flags); |
859 | port->port.flags &= ~ASYNC_INITIALIZED; | ||
860 | 846 | ||
861 | if (--bp->count < 0) { | 847 | if (--bp->count < 0) { |
862 | printk(KERN_INFO "rc%d: rc_shutdown_port: " | 848 | printk(KERN_INFO "rc%d: rc_shutdown_port: " |
@@ -889,6 +875,20 @@ static int carrier_raised(struct tty_port *port) | |||
889 | return CD; | 875 | return CD; |
890 | } | 876 | } |
891 | 877 | ||
878 | static void dtr_rts(struct tty_port *port, int onoff) | ||
879 | { | ||
880 | struct riscom_port *p = container_of(port, struct riscom_port, port); | ||
881 | struct riscom_board *bp = port_Board(p); | ||
882 | unsigned long flags; | ||
883 | |||
884 | spin_lock_irqsave(&riscom_lock, flags); | ||
885 | bp->DTR &= ~(1u << port_No(p)); | ||
886 | if (onoff == 0) | ||
887 | bp->DTR |= (1u << port_No(p)); | ||
888 | rc_out(bp, RC_DTR, bp->DTR); | ||
889 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
890 | } | ||
891 | |||
892 | static int rc_open(struct tty_struct *tty, struct file *filp) | 892 | static int rc_open(struct tty_struct *tty, struct file *filp) |
893 | { | 893 | { |
894 | int board; | 894 | int board; |
@@ -909,14 +909,7 @@ static int rc_open(struct tty_struct *tty, struct file *filp) | |||
909 | if (error) | 909 | if (error) |
910 | return error; | 910 | return error; |
911 | 911 | ||
912 | port->port.count++; | 912 | return tty_port_open(&port->port, tty, filp); |
913 | tty->driver_data = port; | ||
914 | tty_port_tty_set(&port->port, tty); | ||
915 | |||
916 | error = rc_setup_port(tty, bp, port); | ||
917 | if (error == 0) | ||
918 | error = tty_port_block_til_ready(&port->port, tty, filp); | ||
919 | return error; | ||
920 | } | 913 | } |
921 | 914 | ||
922 | static void rc_flush_buffer(struct tty_struct *tty) | 915 | static void rc_flush_buffer(struct tty_struct *tty) |
@@ -950,24 +943,23 @@ static void rc_close_port(struct tty_port *port) | |||
950 | 943 | ||
951 | spin_lock_irqsave(&riscom_lock, flags); | 944 | spin_lock_irqsave(&riscom_lock, flags); |
952 | rp->IER &= ~IER_RXD; | 945 | rp->IER &= ~IER_RXD; |
953 | if (port->flags & ASYNC_INITIALIZED) { | 946 | |
954 | rp->IER &= ~IER_TXRDY; | 947 | rp->IER &= ~IER_TXRDY; |
955 | rp->IER |= IER_TXEMPTY; | 948 | rp->IER |= IER_TXEMPTY; |
956 | rc_out(bp, CD180_CAR, port_No(rp)); | 949 | rc_out(bp, CD180_CAR, port_No(rp)); |
957 | rc_out(bp, CD180_IER, rp->IER); | 950 | rc_out(bp, CD180_IER, rp->IER); |
958 | /* | 951 | /* |
959 | * Before we drop DTR, make sure the UART transmitter | 952 | * Before we drop DTR, make sure the UART transmitter |
960 | * has completely drained; this is especially | 953 | * has completely drained; this is especially |
961 | * important if there is a transmit FIFO! | 954 | * important if there is a transmit FIFO! |
962 | */ | 955 | */ |
963 | timeout = jiffies + HZ; | 956 | timeout = jiffies + HZ; |
964 | while (rp->IER & IER_TXEMPTY) { | 957 | while (rp->IER & IER_TXEMPTY) { |
965 | spin_unlock_irqrestore(&riscom_lock, flags); | 958 | spin_unlock_irqrestore(&riscom_lock, flags); |
966 | msleep_interruptible(jiffies_to_msecs(rp->timeout)); | 959 | msleep_interruptible(jiffies_to_msecs(rp->timeout)); |
967 | spin_lock_irqsave(&riscom_lock, flags); | 960 | spin_lock_irqsave(&riscom_lock, flags); |
968 | if (time_after(jiffies, timeout)) | 961 | if (time_after(jiffies, timeout)) |
969 | break; | 962 | break; |
970 | } | ||
971 | } | 963 | } |
972 | rc_shutdown_port(port->tty, bp, rp); | 964 | rc_shutdown_port(port->tty, bp, rp); |
973 | spin_unlock_irqrestore(&riscom_lock, flags); | 965 | spin_unlock_irqrestore(&riscom_lock, flags); |
@@ -1354,7 +1346,6 @@ static void rc_hangup(struct tty_struct *tty) | |||
1354 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) | 1346 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) |
1355 | return; | 1347 | return; |
1356 | 1348 | ||
1357 | rc_shutdown_port(tty, port_Board(port), port); | ||
1358 | tty_port_hangup(&port->port); | 1349 | tty_port_hangup(&port->port); |
1359 | } | 1350 | } |
1360 | 1351 | ||
@@ -1401,7 +1392,9 @@ static const struct tty_operations riscom_ops = { | |||
1401 | 1392 | ||
1402 | static const struct tty_port_operations riscom_port_ops = { | 1393 | static const struct tty_port_operations riscom_port_ops = { |
1403 | .carrier_raised = carrier_raised, | 1394 | .carrier_raised = carrier_raised, |
1395 | .dtr_rts = dtr_rts, | ||
1404 | .shutdown = rc_close_port, | 1396 | .shutdown = rc_close_port, |
1397 | .activate = rc_activate_port, | ||
1405 | }; | 1398 | }; |
1406 | 1399 | ||
1407 | 1400 | ||
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index bc4ab3e54550..95acb8c880f4 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -282,34 +282,31 @@ static irqreturn_t rtc_interrupt(int irq, void *dev_id) | |||
282 | */ | 282 | */ |
283 | static ctl_table rtc_table[] = { | 283 | static ctl_table rtc_table[] = { |
284 | { | 284 | { |
285 | .ctl_name = CTL_UNNUMBERED, | ||
286 | .procname = "max-user-freq", | 285 | .procname = "max-user-freq", |
287 | .data = &rtc_max_user_freq, | 286 | .data = &rtc_max_user_freq, |
288 | .maxlen = sizeof(int), | 287 | .maxlen = sizeof(int), |
289 | .mode = 0644, | 288 | .mode = 0644, |
290 | .proc_handler = &proc_dointvec, | 289 | .proc_handler = proc_dointvec, |
291 | }, | 290 | }, |
292 | { .ctl_name = 0 } | 291 | { } |
293 | }; | 292 | }; |
294 | 293 | ||
295 | static ctl_table rtc_root[] = { | 294 | static ctl_table rtc_root[] = { |
296 | { | 295 | { |
297 | .ctl_name = CTL_UNNUMBERED, | ||
298 | .procname = "rtc", | 296 | .procname = "rtc", |
299 | .mode = 0555, | 297 | .mode = 0555, |
300 | .child = rtc_table, | 298 | .child = rtc_table, |
301 | }, | 299 | }, |
302 | { .ctl_name = 0 } | 300 | { } |
303 | }; | 301 | }; |
304 | 302 | ||
305 | static ctl_table dev_root[] = { | 303 | static ctl_table dev_root[] = { |
306 | { | 304 | { |
307 | .ctl_name = CTL_DEV, | ||
308 | .procname = "dev", | 305 | .procname = "dev", |
309 | .mode = 0555, | 306 | .mode = 0555, |
310 | .child = rtc_root, | 307 | .child = rtc_root, |
311 | }, | 308 | }, |
312 | { .ctl_name = 0 } | 309 | { } |
313 | }; | 310 | }; |
314 | 311 | ||
315 | static struct ctl_table_header *sysctl_header; | 312 | static struct ctl_table_header *sysctl_header; |
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 1d9100561c8a..99e5272e3c53 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
17 | #include <asm/io.h> | 16 | #include <asm/io.h> |
18 | 17 | ||
@@ -52,7 +51,6 @@ static int scx200_gpio_open(struct inode *inode, struct file *file) | |||
52 | unsigned m = iminor(inode); | 51 | unsigned m = iminor(inode); |
53 | file->private_data = &scx200_gpio_ops; | 52 | file->private_data = &scx200_gpio_ops; |
54 | 53 | ||
55 | cycle_kernel_lock(); | ||
56 | if (m >= MAX_PINS) | 54 | if (m >= MAX_PINS) |
57 | return -EINVAL; | 55 | return -EINVAL; |
58 | return nonseekable_open(inode, file); | 56 | return nonseekable_open(inode, file); |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 8c262aaf7c26..bba727c3807e 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/err.h> | 50 | #include <linux/err.h> |
51 | #include <linux/kfifo.h> | 51 | #include <linux/kfifo.h> |
52 | #include <linux/platform_device.h> | 52 | #include <linux/platform_device.h> |
53 | #include <linux/smp_lock.h> | ||
54 | 53 | ||
55 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
56 | #include <asm/io.h> | 55 | #include <asm/io.h> |
@@ -487,7 +486,7 @@ static struct sonypi_device { | |||
487 | int camera_power; | 486 | int camera_power; |
488 | int bluetooth_power; | 487 | int bluetooth_power; |
489 | struct mutex lock; | 488 | struct mutex lock; |
490 | struct kfifo *fifo; | 489 | struct kfifo fifo; |
491 | spinlock_t fifo_lock; | 490 | spinlock_t fifo_lock; |
492 | wait_queue_head_t fifo_proc_list; | 491 | wait_queue_head_t fifo_proc_list; |
493 | struct fasync_struct *fifo_async; | 492 | struct fasync_struct *fifo_async; |
@@ -496,7 +495,7 @@ static struct sonypi_device { | |||
496 | struct input_dev *input_jog_dev; | 495 | struct input_dev *input_jog_dev; |
497 | struct input_dev *input_key_dev; | 496 | struct input_dev *input_key_dev; |
498 | struct work_struct input_work; | 497 | struct work_struct input_work; |
499 | struct kfifo *input_fifo; | 498 | struct kfifo input_fifo; |
500 | spinlock_t input_fifo_lock; | 499 | spinlock_t input_fifo_lock; |
501 | } sonypi_device; | 500 | } sonypi_device; |
502 | 501 | ||
@@ -777,8 +776,9 @@ static void input_keyrelease(struct work_struct *work) | |||
777 | { | 776 | { |
778 | struct sonypi_keypress kp; | 777 | struct sonypi_keypress kp; |
779 | 778 | ||
780 | while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, | 779 | while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp, |
781 | sizeof(kp)) == sizeof(kp)) { | 780 | sizeof(kp), &sonypi_device.input_fifo_lock) |
781 | == sizeof(kp)) { | ||
782 | msleep(10); | 782 | msleep(10); |
783 | input_report_key(kp.dev, kp.key, 0); | 783 | input_report_key(kp.dev, kp.key, 0); |
784 | input_sync(kp.dev); | 784 | input_sync(kp.dev); |
@@ -827,8 +827,9 @@ static void sonypi_report_input_event(u8 event) | |||
827 | if (kp.dev) { | 827 | if (kp.dev) { |
828 | input_report_key(kp.dev, kp.key, 1); | 828 | input_report_key(kp.dev, kp.key, 1); |
829 | input_sync(kp.dev); | 829 | input_sync(kp.dev); |
830 | kfifo_put(sonypi_device.input_fifo, | 830 | kfifo_in_locked(&sonypi_device.input_fifo, |
831 | (unsigned char *)&kp, sizeof(kp)); | 831 | (unsigned char *)&kp, sizeof(kp), |
832 | &sonypi_device.input_fifo_lock); | ||
832 | schedule_work(&sonypi_device.input_work); | 833 | schedule_work(&sonypi_device.input_work); |
833 | } | 834 | } |
834 | } | 835 | } |
@@ -880,7 +881,8 @@ found: | |||
880 | acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); | 881 | acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); |
881 | #endif | 882 | #endif |
882 | 883 | ||
883 | kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); | 884 | kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event, |
885 | sizeof(event), &sonypi_device.fifo_lock); | ||
884 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); | 886 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); |
885 | wake_up_interruptible(&sonypi_device.fifo_proc_list); | 887 | wake_up_interruptible(&sonypi_device.fifo_proc_list); |
886 | 888 | ||
@@ -902,14 +904,13 @@ static int sonypi_misc_release(struct inode *inode, struct file *file) | |||
902 | 904 | ||
903 | static int sonypi_misc_open(struct inode *inode, struct file *file) | 905 | static int sonypi_misc_open(struct inode *inode, struct file *file) |
904 | { | 906 | { |
905 | lock_kernel(); | ||
906 | mutex_lock(&sonypi_device.lock); | 907 | mutex_lock(&sonypi_device.lock); |
907 | /* Flush input queue on first open */ | 908 | /* Flush input queue on first open */ |
908 | if (!sonypi_device.open_count) | 909 | if (!sonypi_device.open_count) |
909 | kfifo_reset(sonypi_device.fifo); | 910 | kfifo_reset(&sonypi_device.fifo); |
910 | sonypi_device.open_count++; | 911 | sonypi_device.open_count++; |
911 | mutex_unlock(&sonypi_device.lock); | 912 | mutex_unlock(&sonypi_device.lock); |
912 | unlock_kernel(); | 913 | |
913 | return 0; | 914 | return 0; |
914 | } | 915 | } |
915 | 916 | ||
@@ -919,17 +920,18 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
919 | ssize_t ret; | 920 | ssize_t ret; |
920 | unsigned char c; | 921 | unsigned char c; |
921 | 922 | ||
922 | if ((kfifo_len(sonypi_device.fifo) == 0) && | 923 | if ((kfifo_len(&sonypi_device.fifo) == 0) && |
923 | (file->f_flags & O_NONBLOCK)) | 924 | (file->f_flags & O_NONBLOCK)) |
924 | return -EAGAIN; | 925 | return -EAGAIN; |
925 | 926 | ||
926 | ret = wait_event_interruptible(sonypi_device.fifo_proc_list, | 927 | ret = wait_event_interruptible(sonypi_device.fifo_proc_list, |
927 | kfifo_len(sonypi_device.fifo) != 0); | 928 | kfifo_len(&sonypi_device.fifo) != 0); |
928 | if (ret) | 929 | if (ret) |
929 | return ret; | 930 | return ret; |
930 | 931 | ||
931 | while (ret < count && | 932 | while (ret < count && |
932 | (kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) { | 933 | (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c), |
934 | &sonypi_device.fifo_lock) == sizeof(c))) { | ||
933 | if (put_user(c, buf++)) | 935 | if (put_user(c, buf++)) |
934 | return -EFAULT; | 936 | return -EFAULT; |
935 | ret++; | 937 | ret++; |
@@ -946,15 +948,15 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
946 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) | 948 | static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait) |
947 | { | 949 | { |
948 | poll_wait(file, &sonypi_device.fifo_proc_list, wait); | 950 | poll_wait(file, &sonypi_device.fifo_proc_list, wait); |
949 | if (kfifo_len(sonypi_device.fifo)) | 951 | if (kfifo_len(&sonypi_device.fifo)) |
950 | return POLLIN | POLLRDNORM; | 952 | return POLLIN | POLLRDNORM; |
951 | return 0; | 953 | return 0; |
952 | } | 954 | } |
953 | 955 | ||
954 | static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, | 956 | static long sonypi_misc_ioctl(struct file *fp, |
955 | unsigned int cmd, unsigned long arg) | 957 | unsigned int cmd, unsigned long arg) |
956 | { | 958 | { |
957 | int ret = 0; | 959 | long ret = 0; |
958 | void __user *argp = (void __user *)arg; | 960 | void __user *argp = (void __user *)arg; |
959 | u8 val8; | 961 | u8 val8; |
960 | u16 val16; | 962 | u16 val16; |
@@ -1070,7 +1072,8 @@ static const struct file_operations sonypi_misc_fops = { | |||
1070 | .open = sonypi_misc_open, | 1072 | .open = sonypi_misc_open, |
1071 | .release = sonypi_misc_release, | 1073 | .release = sonypi_misc_release, |
1072 | .fasync = sonypi_misc_fasync, | 1074 | .fasync = sonypi_misc_fasync, |
1073 | .ioctl = sonypi_misc_ioctl, | 1075 | .unlocked_ioctl = sonypi_misc_ioctl, |
1076 | .llseek = no_llseek, | ||
1074 | }; | 1077 | }; |
1075 | 1078 | ||
1076 | static struct miscdevice sonypi_misc_device = { | 1079 | static struct miscdevice sonypi_misc_device = { |
@@ -1313,11 +1316,10 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
1313 | "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); | 1316 | "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n"); |
1314 | 1317 | ||
1315 | spin_lock_init(&sonypi_device.fifo_lock); | 1318 | spin_lock_init(&sonypi_device.fifo_lock); |
1316 | sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, | 1319 | error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL); |
1317 | &sonypi_device.fifo_lock); | 1320 | if (error) { |
1318 | if (IS_ERR(sonypi_device.fifo)) { | ||
1319 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); | 1321 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); |
1320 | return PTR_ERR(sonypi_device.fifo); | 1322 | return error; |
1321 | } | 1323 | } |
1322 | 1324 | ||
1323 | init_waitqueue_head(&sonypi_device.fifo_proc_list); | 1325 | init_waitqueue_head(&sonypi_device.fifo_proc_list); |
@@ -1393,12 +1395,10 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
1393 | } | 1395 | } |
1394 | 1396 | ||
1395 | spin_lock_init(&sonypi_device.input_fifo_lock); | 1397 | spin_lock_init(&sonypi_device.input_fifo_lock); |
1396 | sonypi_device.input_fifo = | 1398 | error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE, |
1397 | kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, | 1399 | GFP_KERNEL); |
1398 | &sonypi_device.input_fifo_lock); | 1400 | if (error) { |
1399 | if (IS_ERR(sonypi_device.input_fifo)) { | ||
1400 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); | 1401 | printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); |
1401 | error = PTR_ERR(sonypi_device.input_fifo); | ||
1402 | goto err_inpdev_unregister; | 1402 | goto err_inpdev_unregister; |
1403 | } | 1403 | } |
1404 | 1404 | ||
@@ -1423,7 +1423,7 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
1423 | pci_disable_device(pcidev); | 1423 | pci_disable_device(pcidev); |
1424 | err_put_pcidev: | 1424 | err_put_pcidev: |
1425 | pci_dev_put(pcidev); | 1425 | pci_dev_put(pcidev); |
1426 | kfifo_free(sonypi_device.fifo); | 1426 | kfifo_free(&sonypi_device.fifo); |
1427 | 1427 | ||
1428 | return error; | 1428 | return error; |
1429 | } | 1429 | } |
@@ -1438,7 +1438,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) | |||
1438 | if (useinput) { | 1438 | if (useinput) { |
1439 | input_unregister_device(sonypi_device.input_key_dev); | 1439 | input_unregister_device(sonypi_device.input_key_dev); |
1440 | input_unregister_device(sonypi_device.input_jog_dev); | 1440 | input_unregister_device(sonypi_device.input_jog_dev); |
1441 | kfifo_free(sonypi_device.input_fifo); | 1441 | kfifo_free(&sonypi_device.input_fifo); |
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | misc_deregister(&sonypi_misc_device); | 1444 | misc_deregister(&sonypi_misc_device); |
@@ -1451,7 +1451,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) | |||
1451 | pci_dev_put(sonypi_device.dev); | 1451 | pci_dev_put(sonypi_device.dev); |
1452 | } | 1452 | } |
1453 | 1453 | ||
1454 | kfifo_free(sonypi_device.fifo); | 1454 | kfifo_free(&sonypi_device.fifo); |
1455 | 1455 | ||
1456 | return 0; | 1456 | return 0; |
1457 | } | 1457 | } |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index db6dcfa35ba0..0e511d61f544 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -407,7 +407,7 @@ static unsigned int stl_baudrates[] = { | |||
407 | * Declare all those functions in this driver! | 407 | * Declare all those functions in this driver! |
408 | */ | 408 | */ |
409 | 409 | ||
410 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); | 410 | static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); |
411 | static int stl_brdinit(struct stlbrd *brdp); | 411 | static int stl_brdinit(struct stlbrd *brdp); |
412 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); | 412 | static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); |
413 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); | 413 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); |
@@ -607,7 +607,7 @@ static unsigned int sc26198_baudtable[] = { | |||
607 | */ | 607 | */ |
608 | static const struct file_operations stl_fsiomem = { | 608 | static const struct file_operations stl_fsiomem = { |
609 | .owner = THIS_MODULE, | 609 | .owner = THIS_MODULE, |
610 | .ioctl = stl_memioctl, | 610 | .unlocked_ioctl = stl_memioctl, |
611 | }; | 611 | }; |
612 | 612 | ||
613 | static struct class *stallion_class; | 613 | static struct class *stallion_class; |
@@ -702,6 +702,24 @@ static struct stlbrd *stl_allocbrd(void) | |||
702 | 702 | ||
703 | /*****************************************************************************/ | 703 | /*****************************************************************************/ |
704 | 704 | ||
705 | static int stl_activate(struct tty_port *port, struct tty_struct *tty) | ||
706 | { | ||
707 | struct stlport *portp = container_of(port, struct stlport, port); | ||
708 | if (!portp->tx.buf) { | ||
709 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
710 | if (!portp->tx.buf) | ||
711 | return -ENOMEM; | ||
712 | portp->tx.head = portp->tx.buf; | ||
713 | portp->tx.tail = portp->tx.buf; | ||
714 | } | ||
715 | stl_setport(portp, tty->termios); | ||
716 | portp->sigs = stl_getsignals(portp); | ||
717 | stl_setsignals(portp, 1, 1); | ||
718 | stl_enablerxtx(portp, 1, 1); | ||
719 | stl_startrxtx(portp, 1, 0); | ||
720 | return 0; | ||
721 | } | ||
722 | |||
705 | static int stl_open(struct tty_struct *tty, struct file *filp) | 723 | static int stl_open(struct tty_struct *tty, struct file *filp) |
706 | { | 724 | { |
707 | struct stlport *portp; | 725 | struct stlport *portp; |
@@ -737,32 +755,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
737 | if (portp == NULL) | 755 | if (portp == NULL) |
738 | return -ENODEV; | 756 | return -ENODEV; |
739 | port = &portp->port; | 757 | port = &portp->port; |
758 | return tty_port_open(&portp->port, tty, filp); | ||
740 | 759 | ||
741 | /* | ||
742 | * On the first open of the device setup the port hardware, and | ||
743 | * initialize the per port data structure. | ||
744 | */ | ||
745 | tty_port_tty_set(port, tty); | ||
746 | tty->driver_data = portp; | ||
747 | port->count++; | ||
748 | |||
749 | if ((port->flags & ASYNC_INITIALIZED) == 0) { | ||
750 | if (!portp->tx.buf) { | ||
751 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
752 | if (!portp->tx.buf) | ||
753 | return -ENOMEM; | ||
754 | portp->tx.head = portp->tx.buf; | ||
755 | portp->tx.tail = portp->tx.buf; | ||
756 | } | ||
757 | stl_setport(portp, tty->termios); | ||
758 | portp->sigs = stl_getsignals(portp); | ||
759 | stl_setsignals(portp, 1, 1); | ||
760 | stl_enablerxtx(portp, 1, 1); | ||
761 | stl_startrxtx(portp, 1, 0); | ||
762 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
763 | port->flags |= ASYNC_INITIALIZED; | ||
764 | } | ||
765 | return tty_port_block_til_ready(port, tty, filp); | ||
766 | } | 760 | } |
767 | 761 | ||
768 | /*****************************************************************************/ | 762 | /*****************************************************************************/ |
@@ -826,38 +820,12 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
826 | 820 | ||
827 | /*****************************************************************************/ | 821 | /*****************************************************************************/ |
828 | 822 | ||
829 | static void stl_close(struct tty_struct *tty, struct file *filp) | 823 | static void stl_shutdown(struct tty_port *port) |
830 | { | 824 | { |
831 | struct stlport *portp; | 825 | struct stlport *portp = container_of(port, struct stlport, port); |
832 | struct tty_port *port; | ||
833 | unsigned long flags; | ||
834 | |||
835 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); | ||
836 | |||
837 | portp = tty->driver_data; | ||
838 | BUG_ON(portp == NULL); | ||
839 | |||
840 | port = &portp->port; | ||
841 | |||
842 | if (tty_port_close_start(port, tty, filp) == 0) | ||
843 | return; | ||
844 | /* | ||
845 | * May want to wait for any data to drain before closing. The BUSY | ||
846 | * flag keeps track of whether we are still sending or not - it is | ||
847 | * very accurate for the cd1400, not quite so for the sc26198. | ||
848 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) | ||
849 | */ | ||
850 | stl_waituntilsent(tty, (HZ / 2)); | ||
851 | |||
852 | spin_lock_irqsave(&port->lock, flags); | ||
853 | portp->port.flags &= ~ASYNC_INITIALIZED; | ||
854 | spin_unlock_irqrestore(&port->lock, flags); | ||
855 | |||
856 | stl_disableintrs(portp); | 826 | stl_disableintrs(portp); |
857 | if (tty->termios->c_cflag & HUPCL) | ||
858 | stl_setsignals(portp, 0, 0); | ||
859 | stl_enablerxtx(portp, 0, 0); | 827 | stl_enablerxtx(portp, 0, 0); |
860 | stl_flushbuffer(tty); | 828 | stl_flush(portp); |
861 | portp->istate = 0; | 829 | portp->istate = 0; |
862 | if (portp->tx.buf != NULL) { | 830 | if (portp->tx.buf != NULL) { |
863 | kfree(portp->tx.buf); | 831 | kfree(portp->tx.buf); |
@@ -865,9 +833,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
865 | portp->tx.head = NULL; | 833 | portp->tx.head = NULL; |
866 | portp->tx.tail = NULL; | 834 | portp->tx.tail = NULL; |
867 | } | 835 | } |
836 | } | ||
837 | |||
838 | static void stl_close(struct tty_struct *tty, struct file *filp) | ||
839 | { | ||
840 | struct stlport*portp; | ||
841 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); | ||
868 | 842 | ||
869 | tty_port_close_end(port, tty); | 843 | portp = tty->driver_data; |
870 | tty_port_tty_set(port, NULL); | 844 | BUG_ON(portp == NULL); |
845 | tty_port_close(&portp->port, tty, filp); | ||
871 | } | 846 | } |
872 | 847 | ||
873 | /*****************************************************************************/ | 848 | /*****************************************************************************/ |
@@ -1314,35 +1289,12 @@ static void stl_stop(struct tty_struct *tty) | |||
1314 | 1289 | ||
1315 | static void stl_hangup(struct tty_struct *tty) | 1290 | static void stl_hangup(struct tty_struct *tty) |
1316 | { | 1291 | { |
1317 | struct stlport *portp; | 1292 | struct stlport *portp = tty->driver_data; |
1318 | struct tty_port *port; | ||
1319 | unsigned long flags; | ||
1320 | |||
1321 | pr_debug("stl_hangup(tty=%p)\n", tty); | 1293 | pr_debug("stl_hangup(tty=%p)\n", tty); |
1322 | 1294 | ||
1323 | portp = tty->driver_data; | ||
1324 | if (portp == NULL) | 1295 | if (portp == NULL) |
1325 | return; | 1296 | return; |
1326 | port = &portp->port; | 1297 | tty_port_hangup(&portp->port); |
1327 | |||
1328 | spin_lock_irqsave(&port->lock, flags); | ||
1329 | port->flags &= ~ASYNC_INITIALIZED; | ||
1330 | spin_unlock_irqrestore(&port->lock, flags); | ||
1331 | |||
1332 | stl_disableintrs(portp); | ||
1333 | if (tty->termios->c_cflag & HUPCL) | ||
1334 | stl_setsignals(portp, 0, 0); | ||
1335 | stl_enablerxtx(portp, 0, 0); | ||
1336 | stl_flushbuffer(tty); | ||
1337 | portp->istate = 0; | ||
1338 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
1339 | if (portp->tx.buf != NULL) { | ||
1340 | kfree(portp->tx.buf); | ||
1341 | portp->tx.buf = NULL; | ||
1342 | portp->tx.head = NULL; | ||
1343 | portp->tx.tail = NULL; | ||
1344 | } | ||
1345 | tty_port_hangup(port); | ||
1346 | } | 1298 | } |
1347 | 1299 | ||
1348 | /*****************************************************************************/ | 1300 | /*****************************************************************************/ |
@@ -2486,18 +2438,19 @@ static int stl_getbrdstruct(struct stlbrd __user *arg) | |||
2486 | * collection. | 2438 | * collection. |
2487 | */ | 2439 | */ |
2488 | 2440 | ||
2489 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) | 2441 | static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) |
2490 | { | 2442 | { |
2491 | int brdnr, rc; | 2443 | int brdnr, rc; |
2492 | void __user *argp = (void __user *)arg; | 2444 | void __user *argp = (void __user *)arg; |
2493 | 2445 | ||
2494 | pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg); | 2446 | pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg); |
2495 | 2447 | ||
2496 | brdnr = iminor(ip); | 2448 | brdnr = iminor(fp->f_dentry->d_inode); |
2497 | if (brdnr >= STL_MAXBRDS) | 2449 | if (brdnr >= STL_MAXBRDS) |
2498 | return -ENODEV; | 2450 | return -ENODEV; |
2499 | rc = 0; | 2451 | rc = 0; |
2500 | 2452 | ||
2453 | lock_kernel(); | ||
2501 | switch (cmd) { | 2454 | switch (cmd) { |
2502 | case COM_GETPORTSTATS: | 2455 | case COM_GETPORTSTATS: |
2503 | rc = stl_getportstats(NULL, NULL, argp); | 2456 | rc = stl_getportstats(NULL, NULL, argp); |
@@ -2518,7 +2471,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns | |||
2518 | rc = -ENOIOCTLCMD; | 2471 | rc = -ENOIOCTLCMD; |
2519 | break; | 2472 | break; |
2520 | } | 2473 | } |
2521 | 2474 | unlock_kernel(); | |
2522 | return rc; | 2475 | return rc; |
2523 | } | 2476 | } |
2524 | 2477 | ||
@@ -2549,6 +2502,8 @@ static const struct tty_operations stl_ops = { | |||
2549 | static const struct tty_port_operations stl_port_ops = { | 2502 | static const struct tty_port_operations stl_port_ops = { |
2550 | .carrier_raised = stl_carrier_raised, | 2503 | .carrier_raised = stl_carrier_raised, |
2551 | .dtr_rts = stl_dtr_rts, | 2504 | .dtr_rts = stl_dtr_rts, |
2505 | .activate = stl_activate, | ||
2506 | .shutdown = stl_shutdown, | ||
2552 | }; | 2507 | }; |
2553 | 2508 | ||
2554 | /*****************************************************************************/ | 2509 | /*****************************************************************************/ |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 44203ff599da..1ae2de7d8b4f 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -339,7 +339,7 @@ static struct sysrq_key_op sysrq_term_op = { | |||
339 | 339 | ||
340 | static void moom_callback(struct work_struct *ignored) | 340 | static void moom_callback(struct work_struct *ignored) |
341 | { | 341 | { |
342 | out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0); | 342 | out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0, NULL); |
343 | } | 343 | } |
344 | 344 | ||
345 | static DECLARE_WORK(moom_work, moom_callback); | 345 | static DECLARE_WORK(moom_work, moom_callback); |
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index b3ec9b10e292..cad4eb65f13d 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/smp_lock.h> | ||
25 | 24 | ||
26 | #include <asm/io.h> | 25 | #include <asm/io.h> |
27 | #include <asm/reboot.h> | 26 | #include <asm/reboot.h> |
@@ -38,7 +37,7 @@ MODULE_PARM_DESC(major, "Major device number"); | |||
38 | 37 | ||
39 | static void (*old_machine_restart)(char *command); | 38 | static void (*old_machine_restart)(char *command); |
40 | static void __iomem *tb0219_base; | 39 | static void __iomem *tb0219_base; |
41 | static spinlock_t tb0219_lock; | 40 | static DEFINE_SPINLOCK(tb0219_lock); |
42 | 41 | ||
43 | #define tb0219_read(offset) readw(tb0219_base + (offset)) | 42 | #define tb0219_read(offset) readw(tb0219_base + (offset)) |
44 | #define tb0219_write(offset, value) writew((value), tb0219_base + (offset)) | 43 | #define tb0219_write(offset, value) writew((value), tb0219_base + (offset)) |
@@ -237,7 +236,6 @@ static int tanbac_tb0219_open(struct inode *inode, struct file *file) | |||
237 | { | 236 | { |
238 | unsigned int minor; | 237 | unsigned int minor; |
239 | 238 | ||
240 | cycle_kernel_lock(); | ||
241 | minor = iminor(inode); | 239 | minor = iminor(inode); |
242 | switch (minor) { | 240 | switch (minor) { |
243 | case 0: | 241 | case 0: |
@@ -306,8 +304,6 @@ static int __devinit tb0219_probe(struct platform_device *dev) | |||
306 | return retval; | 304 | return retval; |
307 | } | 305 | } |
308 | 306 | ||
309 | spin_lock_init(&tb0219_lock); | ||
310 | |||
311 | old_machine_restart = _machine_restart; | 307 | old_machine_restart = _machine_restart; |
312 | _machine_restart = tb0219_restart; | 308 | _machine_restart = tb0219_restart; |
313 | 309 | ||
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index 663cd15d7c78..f8bc79f6de34 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c | |||
@@ -68,7 +68,7 @@ | |||
68 | #include <linux/stat.h> | 68 | #include <linux/stat.h> |
69 | #include <linux/proc_fs.h> | 69 | #include <linux/proc_fs.h> |
70 | #include <linux/seq_file.h> | 70 | #include <linux/seq_file.h> |
71 | 71 | #include <linux/smp_lock.h> | |
72 | #include <linux/toshiba.h> | 72 | #include <linux/toshiba.h> |
73 | 73 | ||
74 | #define TOSH_MINOR_DEV 181 | 74 | #define TOSH_MINOR_DEV 181 |
@@ -88,13 +88,13 @@ static int tosh_date; | |||
88 | static int tosh_sci; | 88 | static int tosh_sci; |
89 | static int tosh_fan; | 89 | static int tosh_fan; |
90 | 90 | ||
91 | static int tosh_ioctl(struct inode *, struct file *, unsigned int, | 91 | static long tosh_ioctl(struct file *, unsigned int, |
92 | unsigned long); | 92 | unsigned long); |
93 | 93 | ||
94 | 94 | ||
95 | static const struct file_operations tosh_fops = { | 95 | static const struct file_operations tosh_fops = { |
96 | .owner = THIS_MODULE, | 96 | .owner = THIS_MODULE, |
97 | .ioctl = tosh_ioctl, | 97 | .unlocked_ioctl = tosh_ioctl, |
98 | }; | 98 | }; |
99 | 99 | ||
100 | static struct miscdevice tosh_device = { | 100 | static struct miscdevice tosh_device = { |
@@ -252,8 +252,7 @@ int tosh_smm(SMMRegisters *regs) | |||
252 | EXPORT_SYMBOL(tosh_smm); | 252 | EXPORT_SYMBOL(tosh_smm); |
253 | 253 | ||
254 | 254 | ||
255 | static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, | 255 | static long tosh_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) |
256 | unsigned long arg) | ||
257 | { | 256 | { |
258 | SMMRegisters regs; | 257 | SMMRegisters regs; |
259 | SMMRegisters __user *argp = (SMMRegisters __user *)arg; | 258 | SMMRegisters __user *argp = (SMMRegisters __user *)arg; |
@@ -275,13 +274,16 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, | |||
275 | return -EINVAL; | 274 | return -EINVAL; |
276 | 275 | ||
277 | /* do we need to emulate the fan ? */ | 276 | /* do we need to emulate the fan ? */ |
277 | lock_kernel(); | ||
278 | if (tosh_fan==1) { | 278 | if (tosh_fan==1) { |
279 | if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) { | 279 | if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) { |
280 | err = tosh_emulate_fan(®s); | 280 | err = tosh_emulate_fan(®s); |
281 | unlock_kernel(); | ||
281 | break; | 282 | break; |
282 | } | 283 | } |
283 | } | 284 | } |
284 | err = tosh_smm(®s); | 285 | err = tosh_smm(®s); |
286 | unlock_kernel(); | ||
285 | break; | 287 | break; |
286 | default: | 288 | default: |
287 | return -EINVAL; | 289 | return -EINVAL; |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 47c2d2763456..f06bb37defb1 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | enum tpm_const { | 32 | enum tpm_const { |
33 | TPM_MINOR = 224, /* officially assigned */ | 33 | TPM_MINOR = 224, /* officially assigned */ |
34 | TPM_BUFSIZE = 2048, | 34 | TPM_BUFSIZE = 4096, |
35 | TPM_NUM_DEVICES = 256, | 35 | TPM_NUM_DEVICES = 256, |
36 | }; | 36 | }; |
37 | 37 | ||
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 0b73e4ec1add..2405f17b29dd 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -257,6 +257,10 @@ out: | |||
257 | return size; | 257 | return size; |
258 | } | 258 | } |
259 | 259 | ||
260 | static int itpm; | ||
261 | module_param(itpm, bool, 0444); | ||
262 | MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)"); | ||
263 | |||
260 | /* | 264 | /* |
261 | * If interrupts are used (signaled by an irq set in the vendor structure) | 265 | * If interrupts are used (signaled by an irq set in the vendor structure) |
262 | * tpm.c can skip polling for the data to be available as the interrupt is | 266 | * tpm.c can skip polling for the data to be available as the interrupt is |
@@ -293,7 +297,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) | |||
293 | wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, | 297 | wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, |
294 | &chip->vendor.int_queue); | 298 | &chip->vendor.int_queue); |
295 | status = tpm_tis_status(chip); | 299 | status = tpm_tis_status(chip); |
296 | if ((status & TPM_STS_DATA_EXPECT) == 0) { | 300 | if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { |
297 | rc = -EIO; | 301 | rc = -EIO; |
298 | goto out_err; | 302 | goto out_err; |
299 | } | 303 | } |
@@ -467,6 +471,10 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
467 | "1.2 TPM (device-id 0x%X, rev-id %d)\n", | 471 | "1.2 TPM (device-id 0x%X, rev-id %d)\n", |
468 | vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); | 472 | vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); |
469 | 473 | ||
474 | if (itpm) | ||
475 | dev_info(dev, "Intel iTPM workaround enabled\n"); | ||
476 | |||
477 | |||
470 | /* Figure out the capabilities */ | 478 | /* Figure out the capabilities */ |
471 | intfcaps = | 479 | intfcaps = |
472 | ioread32(chip->vendor.iobase + | 480 | ioread32(chip->vendor.iobase + |
@@ -629,6 +637,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { | |||
629 | {"", 0}, /* User Specified */ | 637 | {"", 0}, /* User Specified */ |
630 | {"", 0} /* Terminator */ | 638 | {"", 0} /* Terminator */ |
631 | }; | 639 | }; |
640 | MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); | ||
632 | 641 | ||
633 | static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) | 642 | static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) |
634 | { | 643 | { |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 59499ee0fe6a..f15df40bc318 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -142,7 +142,6 @@ ssize_t redirected_tty_write(struct file *, const char __user *, | |||
142 | size_t, loff_t *); | 142 | size_t, loff_t *); |
143 | static unsigned int tty_poll(struct file *, poll_table *); | 143 | static unsigned int tty_poll(struct file *, poll_table *); |
144 | static int tty_open(struct inode *, struct file *); | 144 | static int tty_open(struct inode *, struct file *); |
145 | static int tty_release(struct inode *, struct file *); | ||
146 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 145 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
147 | #ifdef CONFIG_COMPAT | 146 | #ifdef CONFIG_COMPAT |
148 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, | 147 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, |
@@ -506,8 +505,6 @@ static void do_tty_hangup(struct work_struct *work) | |||
506 | if (!tty) | 505 | if (!tty) |
507 | return; | 506 | return; |
508 | 507 | ||
509 | /* inuse_filps is protected by the single kernel lock */ | ||
510 | lock_kernel(); | ||
511 | 508 | ||
512 | spin_lock(&redirect_lock); | 509 | spin_lock(&redirect_lock); |
513 | if (redirect && redirect->private_data == tty) { | 510 | if (redirect && redirect->private_data == tty) { |
@@ -516,7 +513,10 @@ static void do_tty_hangup(struct work_struct *work) | |||
516 | } | 513 | } |
517 | spin_unlock(&redirect_lock); | 514 | spin_unlock(&redirect_lock); |
518 | 515 | ||
516 | /* inuse_filps is protected by the single kernel lock */ | ||
517 | lock_kernel(); | ||
519 | check_tty_count(tty, "do_tty_hangup"); | 518 | check_tty_count(tty, "do_tty_hangup"); |
519 | |||
520 | file_list_lock(); | 520 | file_list_lock(); |
521 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ | 521 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
522 | list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { | 522 | list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { |
@@ -708,6 +708,8 @@ void disassociate_ctty(int on_exit) | |||
708 | struct tty_struct *tty; | 708 | struct tty_struct *tty; |
709 | struct pid *tty_pgrp = NULL; | 709 | struct pid *tty_pgrp = NULL; |
710 | 710 | ||
711 | if (!current->signal->leader) | ||
712 | return; | ||
711 | 713 | ||
712 | tty = get_current_tty(); | 714 | tty = get_current_tty(); |
713 | if (tty) { | 715 | if (tty) { |
@@ -773,8 +775,7 @@ void no_tty(void) | |||
773 | { | 775 | { |
774 | struct task_struct *tsk = current; | 776 | struct task_struct *tsk = current; |
775 | lock_kernel(); | 777 | lock_kernel(); |
776 | if (tsk->signal->leader) | 778 | disassociate_ctty(0); |
777 | disassociate_ctty(0); | ||
778 | unlock_kernel(); | 779 | unlock_kernel(); |
779 | proc_clear_tty(tsk); | 780 | proc_clear_tty(tsk); |
780 | } | 781 | } |
@@ -1017,14 +1018,16 @@ out: | |||
1017 | 1018 | ||
1018 | void tty_write_message(struct tty_struct *tty, char *msg) | 1019 | void tty_write_message(struct tty_struct *tty, char *msg) |
1019 | { | 1020 | { |
1020 | lock_kernel(); | ||
1021 | if (tty) { | 1021 | if (tty) { |
1022 | mutex_lock(&tty->atomic_write_lock); | 1022 | mutex_lock(&tty->atomic_write_lock); |
1023 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) | 1023 | lock_kernel(); |
1024 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | ||
1025 | unlock_kernel(); | ||
1024 | tty->ops->write(tty, msg, strlen(msg)); | 1026 | tty->ops->write(tty, msg, strlen(msg)); |
1027 | } else | ||
1028 | unlock_kernel(); | ||
1025 | tty_write_unlock(tty); | 1029 | tty_write_unlock(tty); |
1026 | } | 1030 | } |
1027 | unlock_kernel(); | ||
1028 | return; | 1031 | return; |
1029 | } | 1032 | } |
1030 | 1033 | ||
@@ -1202,14 +1205,21 @@ static int tty_driver_install_tty(struct tty_driver *driver, | |||
1202 | struct tty_struct *tty) | 1205 | struct tty_struct *tty) |
1203 | { | 1206 | { |
1204 | int idx = tty->index; | 1207 | int idx = tty->index; |
1208 | int ret; | ||
1205 | 1209 | ||
1206 | if (driver->ops->install) | 1210 | if (driver->ops->install) { |
1207 | return driver->ops->install(driver, tty); | 1211 | lock_kernel(); |
1212 | ret = driver->ops->install(driver, tty); | ||
1213 | unlock_kernel(); | ||
1214 | return ret; | ||
1215 | } | ||
1208 | 1216 | ||
1209 | if (tty_init_termios(tty) == 0) { | 1217 | if (tty_init_termios(tty) == 0) { |
1218 | lock_kernel(); | ||
1210 | tty_driver_kref_get(driver); | 1219 | tty_driver_kref_get(driver); |
1211 | tty->count++; | 1220 | tty->count++; |
1212 | driver->ttys[idx] = tty; | 1221 | driver->ttys[idx] = tty; |
1222 | unlock_kernel(); | ||
1213 | return 0; | 1223 | return 0; |
1214 | } | 1224 | } |
1215 | return -ENOMEM; | 1225 | return -ENOMEM; |
@@ -1302,10 +1312,14 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1302 | struct tty_struct *tty; | 1312 | struct tty_struct *tty; |
1303 | int retval; | 1313 | int retval; |
1304 | 1314 | ||
1315 | lock_kernel(); | ||
1305 | /* Check if pty master is being opened multiple times */ | 1316 | /* Check if pty master is being opened multiple times */ |
1306 | if (driver->subtype == PTY_TYPE_MASTER && | 1317 | if (driver->subtype == PTY_TYPE_MASTER && |
1307 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) | 1318 | (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { |
1319 | unlock_kernel(); | ||
1308 | return ERR_PTR(-EIO); | 1320 | return ERR_PTR(-EIO); |
1321 | } | ||
1322 | unlock_kernel(); | ||
1309 | 1323 | ||
1310 | /* | 1324 | /* |
1311 | * First time open is complex, especially for PTY devices. | 1325 | * First time open is complex, especially for PTY devices. |
@@ -1335,7 +1349,6 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, | |||
1335 | * If we fail here just call release_tty to clean up. No need | 1349 | * If we fail here just call release_tty to clean up. No need |
1336 | * to decrement the use counts, as release_tty doesn't care. | 1350 | * to decrement the use counts, as release_tty doesn't care. |
1337 | */ | 1351 | */ |
1338 | |||
1339 | retval = tty_ldisc_setup(tty, tty->link); | 1352 | retval = tty_ldisc_setup(tty, tty->link); |
1340 | if (retval) | 1353 | if (retval) |
1341 | goto release_mem_out; | 1354 | goto release_mem_out; |
@@ -1350,7 +1363,9 @@ release_mem_out: | |||
1350 | if (printk_ratelimit()) | 1363 | if (printk_ratelimit()) |
1351 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " | 1364 | printk(KERN_INFO "tty_init_dev: ldisc open failed, " |
1352 | "clearing slot %d\n", idx); | 1365 | "clearing slot %d\n", idx); |
1366 | lock_kernel(); | ||
1353 | release_tty(tty, idx); | 1367 | release_tty(tty, idx); |
1368 | unlock_kernel(); | ||
1354 | return ERR_PTR(retval); | 1369 | return ERR_PTR(retval); |
1355 | } | 1370 | } |
1356 | 1371 | ||
@@ -1464,7 +1479,17 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1464 | tty_kref_put(tty); | 1479 | tty_kref_put(tty); |
1465 | } | 1480 | } |
1466 | 1481 | ||
1467 | /* | 1482 | /** |
1483 | * tty_release - vfs callback for close | ||
1484 | * @inode: inode of tty | ||
1485 | * @filp: file pointer for handle to tty | ||
1486 | * | ||
1487 | * Called the last time each file handle is closed that references | ||
1488 | * this tty. There may however be several such references. | ||
1489 | * | ||
1490 | * Locking: | ||
1491 | * Takes bkl. See tty_release_dev | ||
1492 | * | ||
1468 | * Even releasing the tty structures is a tricky business.. We have | 1493 | * Even releasing the tty structures is a tricky business.. We have |
1469 | * to be very careful that the structures are all released at the | 1494 | * to be very careful that the structures are all released at the |
1470 | * same time, as interrupts might otherwise get the wrong pointers. | 1495 | * same time, as interrupts might otherwise get the wrong pointers. |
@@ -1472,20 +1497,20 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1472 | * WSH 09/09/97: rewritten to avoid some nasty race conditions that could | 1497 | * WSH 09/09/97: rewritten to avoid some nasty race conditions that could |
1473 | * lead to double frees or releasing memory still in use. | 1498 | * lead to double frees or releasing memory still in use. |
1474 | */ | 1499 | */ |
1475 | void tty_release_dev(struct file *filp) | 1500 | |
1501 | int tty_release(struct inode *inode, struct file *filp) | ||
1476 | { | 1502 | { |
1477 | struct tty_struct *tty, *o_tty; | 1503 | struct tty_struct *tty, *o_tty; |
1478 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1504 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1479 | int devpts; | 1505 | int devpts; |
1480 | int idx; | 1506 | int idx; |
1481 | char buf[64]; | 1507 | char buf[64]; |
1482 | struct inode *inode; | ||
1483 | 1508 | ||
1484 | inode = filp->f_path.dentry->d_inode; | ||
1485 | tty = (struct tty_struct *)filp->private_data; | 1509 | tty = (struct tty_struct *)filp->private_data; |
1486 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1510 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1487 | return; | 1511 | return 0; |
1488 | 1512 | ||
1513 | lock_kernel(); | ||
1489 | check_tty_count(tty, "tty_release_dev"); | 1514 | check_tty_count(tty, "tty_release_dev"); |
1490 | 1515 | ||
1491 | tty_fasync(-1, filp, 0); | 1516 | tty_fasync(-1, filp, 0); |
@@ -1500,19 +1525,22 @@ void tty_release_dev(struct file *filp) | |||
1500 | if (idx < 0 || idx >= tty->driver->num) { | 1525 | if (idx < 0 || idx >= tty->driver->num) { |
1501 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " | 1526 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " |
1502 | "free (%s)\n", tty->name); | 1527 | "free (%s)\n", tty->name); |
1503 | return; | 1528 | unlock_kernel(); |
1529 | return 0; | ||
1504 | } | 1530 | } |
1505 | if (!devpts) { | 1531 | if (!devpts) { |
1506 | if (tty != tty->driver->ttys[idx]) { | 1532 | if (tty != tty->driver->ttys[idx]) { |
1533 | unlock_kernel(); | ||
1507 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " | 1534 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " |
1508 | "for (%s)\n", idx, tty->name); | 1535 | "for (%s)\n", idx, tty->name); |
1509 | return; | 1536 | return 0; |
1510 | } | 1537 | } |
1511 | if (tty->termios != tty->driver->termios[idx]) { | 1538 | if (tty->termios != tty->driver->termios[idx]) { |
1539 | unlock_kernel(); | ||
1512 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " | 1540 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " |
1513 | "for (%s)\n", | 1541 | "for (%s)\n", |
1514 | idx, tty->name); | 1542 | idx, tty->name); |
1515 | return; | 1543 | return 0; |
1516 | } | 1544 | } |
1517 | } | 1545 | } |
1518 | #endif | 1546 | #endif |
@@ -1526,26 +1554,30 @@ void tty_release_dev(struct file *filp) | |||
1526 | if (tty->driver->other && | 1554 | if (tty->driver->other && |
1527 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 1555 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { |
1528 | if (o_tty != tty->driver->other->ttys[idx]) { | 1556 | if (o_tty != tty->driver->other->ttys[idx]) { |
1557 | unlock_kernel(); | ||
1529 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " | 1558 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " |
1530 | "not o_tty for (%s)\n", | 1559 | "not o_tty for (%s)\n", |
1531 | idx, tty->name); | 1560 | idx, tty->name); |
1532 | return; | 1561 | return 0 ; |
1533 | } | 1562 | } |
1534 | if (o_tty->termios != tty->driver->other->termios[idx]) { | 1563 | if (o_tty->termios != tty->driver->other->termios[idx]) { |
1564 | unlock_kernel(); | ||
1535 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " | 1565 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " |
1536 | "not o_termios for (%s)\n", | 1566 | "not o_termios for (%s)\n", |
1537 | idx, tty->name); | 1567 | idx, tty->name); |
1538 | return; | 1568 | return 0; |
1539 | } | 1569 | } |
1540 | if (o_tty->link != tty) { | 1570 | if (o_tty->link != tty) { |
1571 | unlock_kernel(); | ||
1541 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); | 1572 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); |
1542 | return; | 1573 | return 0; |
1543 | } | 1574 | } |
1544 | } | 1575 | } |
1545 | #endif | 1576 | #endif |
1546 | if (tty->ops->close) | 1577 | if (tty->ops->close) |
1547 | tty->ops->close(tty, filp); | 1578 | tty->ops->close(tty, filp); |
1548 | 1579 | ||
1580 | unlock_kernel(); | ||
1549 | /* | 1581 | /* |
1550 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1582 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1551 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1583 | * any waiters on tty->read_wait or tty->write_wait. We test the |
@@ -1568,6 +1600,7 @@ void tty_release_dev(struct file *filp) | |||
1568 | opens on /dev/tty */ | 1600 | opens on /dev/tty */ |
1569 | 1601 | ||
1570 | mutex_lock(&tty_mutex); | 1602 | mutex_lock(&tty_mutex); |
1603 | lock_kernel(); | ||
1571 | tty_closing = tty->count <= 1; | 1604 | tty_closing = tty->count <= 1; |
1572 | o_tty_closing = o_tty && | 1605 | o_tty_closing = o_tty && |
1573 | (o_tty->count <= (pty_master ? 1 : 0)); | 1606 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1598,6 +1631,7 @@ void tty_release_dev(struct file *filp) | |||
1598 | 1631 | ||
1599 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " | 1632 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " |
1600 | "active!\n", tty_name(tty, buf)); | 1633 | "active!\n", tty_name(tty, buf)); |
1634 | unlock_kernel(); | ||
1601 | mutex_unlock(&tty_mutex); | 1635 | mutex_unlock(&tty_mutex); |
1602 | schedule(); | 1636 | schedule(); |
1603 | } | 1637 | } |
@@ -1661,8 +1695,10 @@ void tty_release_dev(struct file *filp) | |||
1661 | mutex_unlock(&tty_mutex); | 1695 | mutex_unlock(&tty_mutex); |
1662 | 1696 | ||
1663 | /* check whether both sides are closing ... */ | 1697 | /* check whether both sides are closing ... */ |
1664 | if (!tty_closing || (o_tty && !o_tty_closing)) | 1698 | if (!tty_closing || (o_tty && !o_tty_closing)) { |
1665 | return; | 1699 | unlock_kernel(); |
1700 | return 0; | ||
1701 | } | ||
1666 | 1702 | ||
1667 | #ifdef TTY_DEBUG_HANGUP | 1703 | #ifdef TTY_DEBUG_HANGUP |
1668 | printk(KERN_DEBUG "freeing tty structure..."); | 1704 | printk(KERN_DEBUG "freeing tty structure..."); |
@@ -1680,10 +1716,12 @@ void tty_release_dev(struct file *filp) | |||
1680 | /* Make this pty number available for reallocation */ | 1716 | /* Make this pty number available for reallocation */ |
1681 | if (devpts) | 1717 | if (devpts) |
1682 | devpts_kill_index(inode, idx); | 1718 | devpts_kill_index(inode, idx); |
1719 | unlock_kernel(); | ||
1720 | return 0; | ||
1683 | } | 1721 | } |
1684 | 1722 | ||
1685 | /** | 1723 | /** |
1686 | * __tty_open - open a tty device | 1724 | * tty_open - open a tty device |
1687 | * @inode: inode of device file | 1725 | * @inode: inode of device file |
1688 | * @filp: file pointer to tty | 1726 | * @filp: file pointer to tty |
1689 | * | 1727 | * |
@@ -1703,7 +1741,7 @@ void tty_release_dev(struct file *filp) | |||
1703 | * ->siglock protects ->signal/->sighand | 1741 | * ->siglock protects ->signal/->sighand |
1704 | */ | 1742 | */ |
1705 | 1743 | ||
1706 | static int __tty_open(struct inode *inode, struct file *filp) | 1744 | static int tty_open(struct inode *inode, struct file *filp) |
1707 | { | 1745 | { |
1708 | struct tty_struct *tty = NULL; | 1746 | struct tty_struct *tty = NULL; |
1709 | int noctty, retval; | 1747 | int noctty, retval; |
@@ -1720,10 +1758,12 @@ retry_open: | |||
1720 | retval = 0; | 1758 | retval = 0; |
1721 | 1759 | ||
1722 | mutex_lock(&tty_mutex); | 1760 | mutex_lock(&tty_mutex); |
1761 | lock_kernel(); | ||
1723 | 1762 | ||
1724 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { | 1763 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { |
1725 | tty = get_current_tty(); | 1764 | tty = get_current_tty(); |
1726 | if (!tty) { | 1765 | if (!tty) { |
1766 | unlock_kernel(); | ||
1727 | mutex_unlock(&tty_mutex); | 1767 | mutex_unlock(&tty_mutex); |
1728 | return -ENXIO; | 1768 | return -ENXIO; |
1729 | } | 1769 | } |
@@ -1755,12 +1795,14 @@ retry_open: | |||
1755 | goto got_driver; | 1795 | goto got_driver; |
1756 | } | 1796 | } |
1757 | } | 1797 | } |
1798 | unlock_kernel(); | ||
1758 | mutex_unlock(&tty_mutex); | 1799 | mutex_unlock(&tty_mutex); |
1759 | return -ENODEV; | 1800 | return -ENODEV; |
1760 | } | 1801 | } |
1761 | 1802 | ||
1762 | driver = get_tty_driver(device, &index); | 1803 | driver = get_tty_driver(device, &index); |
1763 | if (!driver) { | 1804 | if (!driver) { |
1805 | unlock_kernel(); | ||
1764 | mutex_unlock(&tty_mutex); | 1806 | mutex_unlock(&tty_mutex); |
1765 | return -ENODEV; | 1807 | return -ENODEV; |
1766 | } | 1808 | } |
@@ -1770,6 +1812,7 @@ got_driver: | |||
1770 | tty = tty_driver_lookup_tty(driver, inode, index); | 1812 | tty = tty_driver_lookup_tty(driver, inode, index); |
1771 | 1813 | ||
1772 | if (IS_ERR(tty)) { | 1814 | if (IS_ERR(tty)) { |
1815 | unlock_kernel(); | ||
1773 | mutex_unlock(&tty_mutex); | 1816 | mutex_unlock(&tty_mutex); |
1774 | return PTR_ERR(tty); | 1817 | return PTR_ERR(tty); |
1775 | } | 1818 | } |
@@ -1784,8 +1827,10 @@ got_driver: | |||
1784 | 1827 | ||
1785 | mutex_unlock(&tty_mutex); | 1828 | mutex_unlock(&tty_mutex); |
1786 | tty_driver_kref_put(driver); | 1829 | tty_driver_kref_put(driver); |
1787 | if (IS_ERR(tty)) | 1830 | if (IS_ERR(tty)) { |
1831 | unlock_kernel(); | ||
1788 | return PTR_ERR(tty); | 1832 | return PTR_ERR(tty); |
1833 | } | ||
1789 | 1834 | ||
1790 | filp->private_data = tty; | 1835 | filp->private_data = tty; |
1791 | file_move(filp, &tty->tty_files); | 1836 | file_move(filp, &tty->tty_files); |
@@ -1813,11 +1858,15 @@ got_driver: | |||
1813 | printk(KERN_DEBUG "error %d in opening %s...", retval, | 1858 | printk(KERN_DEBUG "error %d in opening %s...", retval, |
1814 | tty->name); | 1859 | tty->name); |
1815 | #endif | 1860 | #endif |
1816 | tty_release_dev(filp); | 1861 | tty_release(inode, filp); |
1817 | if (retval != -ERESTARTSYS) | 1862 | if (retval != -ERESTARTSYS) { |
1863 | unlock_kernel(); | ||
1818 | return retval; | 1864 | return retval; |
1819 | if (signal_pending(current)) | 1865 | } |
1866 | if (signal_pending(current)) { | ||
1867 | unlock_kernel(); | ||
1820 | return retval; | 1868 | return retval; |
1869 | } | ||
1821 | schedule(); | 1870 | schedule(); |
1822 | /* | 1871 | /* |
1823 | * Need to reset f_op in case a hangup happened. | 1872 | * Need to reset f_op in case a hangup happened. |
@@ -1826,8 +1875,11 @@ got_driver: | |||
1826 | filp->f_op = &tty_fops; | 1875 | filp->f_op = &tty_fops; |
1827 | goto retry_open; | 1876 | goto retry_open; |
1828 | } | 1877 | } |
1878 | unlock_kernel(); | ||
1879 | |||
1829 | 1880 | ||
1830 | mutex_lock(&tty_mutex); | 1881 | mutex_lock(&tty_mutex); |
1882 | lock_kernel(); | ||
1831 | spin_lock_irq(¤t->sighand->siglock); | 1883 | spin_lock_irq(¤t->sighand->siglock); |
1832 | if (!noctty && | 1884 | if (!noctty && |
1833 | current->signal->leader && | 1885 | current->signal->leader && |
@@ -1835,45 +1887,14 @@ got_driver: | |||
1835 | tty->session == NULL) | 1887 | tty->session == NULL) |
1836 | __proc_set_tty(current, tty); | 1888 | __proc_set_tty(current, tty); |
1837 | spin_unlock_irq(¤t->sighand->siglock); | 1889 | spin_unlock_irq(¤t->sighand->siglock); |
1890 | unlock_kernel(); | ||
1838 | mutex_unlock(&tty_mutex); | 1891 | mutex_unlock(&tty_mutex); |
1839 | return 0; | 1892 | return 0; |
1840 | } | 1893 | } |
1841 | 1894 | ||
1842 | /* BKL pushdown: scary code avoidance wrapper */ | ||
1843 | static int tty_open(struct inode *inode, struct file *filp) | ||
1844 | { | ||
1845 | int ret; | ||
1846 | |||
1847 | lock_kernel(); | ||
1848 | ret = __tty_open(inode, filp); | ||
1849 | unlock_kernel(); | ||
1850 | return ret; | ||
1851 | } | ||
1852 | |||
1853 | |||
1854 | 1895 | ||
1855 | 1896 | ||
1856 | /** | 1897 | /** |
1857 | * tty_release - vfs callback for close | ||
1858 | * @inode: inode of tty | ||
1859 | * @filp: file pointer for handle to tty | ||
1860 | * | ||
1861 | * Called the last time each file handle is closed that references | ||
1862 | * this tty. There may however be several such references. | ||
1863 | * | ||
1864 | * Locking: | ||
1865 | * Takes bkl. See tty_release_dev | ||
1866 | */ | ||
1867 | |||
1868 | static int tty_release(struct inode *inode, struct file *filp) | ||
1869 | { | ||
1870 | lock_kernel(); | ||
1871 | tty_release_dev(filp); | ||
1872 | unlock_kernel(); | ||
1873 | return 0; | ||
1874 | } | ||
1875 | |||
1876 | /** | ||
1877 | * tty_poll - check tty status | 1898 | * tty_poll - check tty status |
1878 | * @filp: file being polled | 1899 | * @filp: file being polled |
1879 | * @wait: poll wait structures to update | 1900 | * @wait: poll wait structures to update |
@@ -2317,9 +2338,7 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) | |||
2317 | if (get_user(ldisc, p)) | 2338 | if (get_user(ldisc, p)) |
2318 | return -EFAULT; | 2339 | return -EFAULT; |
2319 | 2340 | ||
2320 | lock_kernel(); | ||
2321 | ret = tty_set_ldisc(tty, ldisc); | 2341 | ret = tty_set_ldisc(tty, ldisc); |
2322 | unlock_kernel(); | ||
2323 | 2342 | ||
2324 | return ret; | 2343 | return ret; |
2325 | } | 2344 | } |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 8e67d5c642a4..6bd5f8866c74 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -315,7 +315,7 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); | |||
315 | * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour | 315 | * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour |
316 | * we need to carefully set the bits when the user does not get the | 316 | * we need to carefully set the bits when the user does not get the |
317 | * desired speed. We allow small margins and preserve as much of possible | 317 | * desired speed. We allow small margins and preserve as much of possible |
318 | * of the input intent to keep compatiblity. | 318 | * of the input intent to keep compatibility. |
319 | * | 319 | * |
320 | * Locking: Caller should hold termios lock. This is already held | 320 | * Locking: Caller should hold termios lock. This is already held |
321 | * when calling this function from the driver termios handler. | 321 | * when calling this function from the driver termios handler. |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index feb55075819b..3f653f7d849f 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <linux/vt_kern.h> | 34 | #include <linux/vt_kern.h> |
35 | #include <linux/selection.h> | 35 | #include <linux/selection.h> |
36 | 36 | ||
37 | #include <linux/smp_lock.h> /* For the moment */ | ||
38 | |||
37 | #include <linux/kmod.h> | 39 | #include <linux/kmod.h> |
38 | #include <linux/nsproxy.h> | 40 | #include <linux/nsproxy.h> |
39 | 41 | ||
@@ -443,8 +445,14 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | |||
443 | static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) | 445 | static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) |
444 | { | 446 | { |
445 | WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); | 447 | WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags)); |
446 | if (ld->ops->open) | 448 | if (ld->ops->open) { |
447 | return ld->ops->open(tty); | 449 | int ret; |
450 | /* BKL here locks verus a hangup event */ | ||
451 | lock_kernel(); | ||
452 | ret = ld->ops->open(tty); | ||
453 | unlock_kernel(); | ||
454 | return ret; | ||
455 | } | ||
448 | return 0; | 456 | return 0; |
449 | } | 457 | } |
450 | 458 | ||
@@ -545,6 +553,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
545 | if (IS_ERR(new_ldisc)) | 553 | if (IS_ERR(new_ldisc)) |
546 | return PTR_ERR(new_ldisc); | 554 | return PTR_ERR(new_ldisc); |
547 | 555 | ||
556 | lock_kernel(); | ||
548 | /* | 557 | /* |
549 | * We need to look at the tty locking here for pty/tty pairs | 558 | * We need to look at the tty locking here for pty/tty pairs |
550 | * when both sides try to change in parallel. | 559 | * when both sides try to change in parallel. |
@@ -558,10 +567,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
558 | */ | 567 | */ |
559 | 568 | ||
560 | if (tty->ldisc->ops->num == ldisc) { | 569 | if (tty->ldisc->ops->num == ldisc) { |
570 | unlock_kernel(); | ||
561 | tty_ldisc_put(new_ldisc); | 571 | tty_ldisc_put(new_ldisc); |
562 | return 0; | 572 | return 0; |
563 | } | 573 | } |
564 | 574 | ||
575 | unlock_kernel(); | ||
565 | /* | 576 | /* |
566 | * Problem: What do we do if this blocks ? | 577 | * Problem: What do we do if this blocks ? |
567 | * We could deadlock here | 578 | * We could deadlock here |
@@ -582,6 +593,9 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
582 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); | 593 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); |
583 | mutex_lock(&tty->ldisc_mutex); | 594 | mutex_lock(&tty->ldisc_mutex); |
584 | } | 595 | } |
596 | |||
597 | lock_kernel(); | ||
598 | |||
585 | set_bit(TTY_LDISC_CHANGING, &tty->flags); | 599 | set_bit(TTY_LDISC_CHANGING, &tty->flags); |
586 | 600 | ||
587 | /* | 601 | /* |
@@ -592,6 +606,8 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
592 | tty->receive_room = 0; | 606 | tty->receive_room = 0; |
593 | 607 | ||
594 | o_ldisc = tty->ldisc; | 608 | o_ldisc = tty->ldisc; |
609 | |||
610 | unlock_kernel(); | ||
595 | /* | 611 | /* |
596 | * Make sure we don't change while someone holds a | 612 | * Make sure we don't change while someone holds a |
597 | * reference to the line discipline. The TTY_LDISC bit | 613 | * reference to the line discipline. The TTY_LDISC bit |
@@ -617,12 +633,14 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
617 | flush_scheduled_work(); | 633 | flush_scheduled_work(); |
618 | 634 | ||
619 | mutex_lock(&tty->ldisc_mutex); | 635 | mutex_lock(&tty->ldisc_mutex); |
636 | lock_kernel(); | ||
620 | if (test_bit(TTY_HUPPED, &tty->flags)) { | 637 | if (test_bit(TTY_HUPPED, &tty->flags)) { |
621 | /* We were raced by the hangup method. It will have stomped | 638 | /* We were raced by the hangup method. It will have stomped |
622 | the ldisc data and closed the ldisc down */ | 639 | the ldisc data and closed the ldisc down */ |
623 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 640 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
624 | mutex_unlock(&tty->ldisc_mutex); | 641 | mutex_unlock(&tty->ldisc_mutex); |
625 | tty_ldisc_put(new_ldisc); | 642 | tty_ldisc_put(new_ldisc); |
643 | unlock_kernel(); | ||
626 | return -EIO; | 644 | return -EIO; |
627 | } | 645 | } |
628 | 646 | ||
@@ -664,6 +682,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
664 | if (o_work) | 682 | if (o_work) |
665 | schedule_delayed_work(&o_tty->buf.work, 1); | 683 | schedule_delayed_work(&o_tty->buf.work, 1); |
666 | mutex_unlock(&tty->ldisc_mutex); | 684 | mutex_unlock(&tty->ldisc_mutex); |
685 | unlock_kernel(); | ||
667 | return retval; | 686 | return retval; |
668 | } | 687 | } |
669 | 688 | ||
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index c63f3d33914a..be492dd66437 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -25,19 +25,21 @@ void tty_port_init(struct tty_port *port) | |||
25 | init_waitqueue_head(&port->close_wait); | 25 | init_waitqueue_head(&port->close_wait); |
26 | init_waitqueue_head(&port->delta_msr_wait); | 26 | init_waitqueue_head(&port->delta_msr_wait); |
27 | mutex_init(&port->mutex); | 27 | mutex_init(&port->mutex); |
28 | mutex_init(&port->buf_mutex); | ||
28 | spin_lock_init(&port->lock); | 29 | spin_lock_init(&port->lock); |
29 | port->close_delay = (50 * HZ) / 100; | 30 | port->close_delay = (50 * HZ) / 100; |
30 | port->closing_wait = (3000 * HZ) / 100; | 31 | port->closing_wait = (3000 * HZ) / 100; |
32 | kref_init(&port->kref); | ||
31 | } | 33 | } |
32 | EXPORT_SYMBOL(tty_port_init); | 34 | EXPORT_SYMBOL(tty_port_init); |
33 | 35 | ||
34 | int tty_port_alloc_xmit_buf(struct tty_port *port) | 36 | int tty_port_alloc_xmit_buf(struct tty_port *port) |
35 | { | 37 | { |
36 | /* We may sleep in get_zeroed_page() */ | 38 | /* We may sleep in get_zeroed_page() */ |
37 | mutex_lock(&port->mutex); | 39 | mutex_lock(&port->buf_mutex); |
38 | if (port->xmit_buf == NULL) | 40 | if (port->xmit_buf == NULL) |
39 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | 41 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); |
40 | mutex_unlock(&port->mutex); | 42 | mutex_unlock(&port->buf_mutex); |
41 | if (port->xmit_buf == NULL) | 43 | if (port->xmit_buf == NULL) |
42 | return -ENOMEM; | 44 | return -ENOMEM; |
43 | return 0; | 45 | return 0; |
@@ -46,15 +48,32 @@ EXPORT_SYMBOL(tty_port_alloc_xmit_buf); | |||
46 | 48 | ||
47 | void tty_port_free_xmit_buf(struct tty_port *port) | 49 | void tty_port_free_xmit_buf(struct tty_port *port) |
48 | { | 50 | { |
49 | mutex_lock(&port->mutex); | 51 | mutex_lock(&port->buf_mutex); |
50 | if (port->xmit_buf != NULL) { | 52 | if (port->xmit_buf != NULL) { |
51 | free_page((unsigned long)port->xmit_buf); | 53 | free_page((unsigned long)port->xmit_buf); |
52 | port->xmit_buf = NULL; | 54 | port->xmit_buf = NULL; |
53 | } | 55 | } |
54 | mutex_unlock(&port->mutex); | 56 | mutex_unlock(&port->buf_mutex); |
55 | } | 57 | } |
56 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | 58 | EXPORT_SYMBOL(tty_port_free_xmit_buf); |
57 | 59 | ||
60 | static void tty_port_destructor(struct kref *kref) | ||
61 | { | ||
62 | struct tty_port *port = container_of(kref, struct tty_port, kref); | ||
63 | if (port->xmit_buf) | ||
64 | free_page((unsigned long)port->xmit_buf); | ||
65 | if (port->ops->destruct) | ||
66 | port->ops->destruct(port); | ||
67 | else | ||
68 | kfree(port); | ||
69 | } | ||
70 | |||
71 | void tty_port_put(struct tty_port *port) | ||
72 | { | ||
73 | if (port) | ||
74 | kref_put(&port->kref, tty_port_destructor); | ||
75 | } | ||
76 | EXPORT_SYMBOL(tty_port_put); | ||
58 | 77 | ||
59 | /** | 78 | /** |
60 | * tty_port_tty_get - get a tty reference | 79 | * tty_port_tty_get - get a tty reference |
@@ -99,10 +118,11 @@ EXPORT_SYMBOL(tty_port_tty_set); | |||
99 | 118 | ||
100 | static void tty_port_shutdown(struct tty_port *port) | 119 | static void tty_port_shutdown(struct tty_port *port) |
101 | { | 120 | { |
121 | mutex_lock(&port->mutex); | ||
102 | if (port->ops->shutdown && | 122 | if (port->ops->shutdown && |
103 | test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) | 123 | test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) |
104 | port->ops->shutdown(port); | 124 | port->ops->shutdown(port); |
105 | 125 | mutex_unlock(&port->mutex); | |
106 | } | 126 | } |
107 | 127 | ||
108 | /** | 128 | /** |
@@ -120,8 +140,10 @@ void tty_port_hangup(struct tty_port *port) | |||
120 | spin_lock_irqsave(&port->lock, flags); | 140 | spin_lock_irqsave(&port->lock, flags); |
121 | port->count = 0; | 141 | port->count = 0; |
122 | port->flags &= ~ASYNC_NORMAL_ACTIVE; | 142 | port->flags &= ~ASYNC_NORMAL_ACTIVE; |
123 | if (port->tty) | 143 | if (port->tty) { |
144 | set_bit(TTY_IO_ERROR, &port->tty->flags); | ||
124 | tty_kref_put(port->tty); | 145 | tty_kref_put(port->tty); |
146 | } | ||
125 | port->tty = NULL; | 147 | port->tty = NULL; |
126 | spin_unlock_irqrestore(&port->lock, flags); | 148 | spin_unlock_irqrestore(&port->lock, flags); |
127 | wake_up_interruptible(&port->open_wait); | 149 | wake_up_interruptible(&port->open_wait); |
@@ -198,7 +220,7 @@ EXPORT_SYMBOL(tty_port_lower_dtr_rts); | |||
198 | * management of these lines. Note that the dtr/rts raise is done each | 220 | * management of these lines. Note that the dtr/rts raise is done each |
199 | * iteration as a hangup may have previously dropped them while we wait. | 221 | * iteration as a hangup may have previously dropped them while we wait. |
200 | */ | 222 | */ |
201 | 223 | ||
202 | int tty_port_block_til_ready(struct tty_port *port, | 224 | int tty_port_block_til_ready(struct tty_port *port, |
203 | struct tty_struct *tty, struct file *filp) | 225 | struct tty_struct *tty, struct file *filp) |
204 | { | 226 | { |
@@ -253,7 +275,8 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
253 | tty_port_raise_dtr_rts(port); | 275 | tty_port_raise_dtr_rts(port); |
254 | 276 | ||
255 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); | 277 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); |
256 | /* Check for a hangup or uninitialised port. Return accordingly */ | 278 | /* Check for a hangup or uninitialised port. |
279 | Return accordingly */ | ||
257 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { | 280 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { |
258 | if (port->flags & ASYNC_HUP_NOTIFY) | 281 | if (port->flags & ASYNC_HUP_NOTIFY) |
259 | retval = -EAGAIN; | 282 | retval = -EAGAIN; |
@@ -285,11 +308,11 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
285 | port->flags |= ASYNC_NORMAL_ACTIVE; | 308 | port->flags |= ASYNC_NORMAL_ACTIVE; |
286 | spin_unlock_irqrestore(&port->lock, flags); | 309 | spin_unlock_irqrestore(&port->lock, flags); |
287 | return retval; | 310 | return retval; |
288 | |||
289 | } | 311 | } |
290 | EXPORT_SYMBOL(tty_port_block_til_ready); | 312 | EXPORT_SYMBOL(tty_port_block_til_ready); |
291 | 313 | ||
292 | int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp) | 314 | int tty_port_close_start(struct tty_port *port, |
315 | struct tty_struct *tty, struct file *filp) | ||
293 | { | 316 | { |
294 | unsigned long flags; | 317 | unsigned long flags; |
295 | 318 | ||
@@ -299,7 +322,7 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f | |||
299 | return 0; | 322 | return 0; |
300 | } | 323 | } |
301 | 324 | ||
302 | if( tty->count == 1 && port->count != 1) { | 325 | if (tty->count == 1 && port->count != 1) { |
303 | printk(KERN_WARNING | 326 | printk(KERN_WARNING |
304 | "tty_port_close_start: tty->count = 1 port count = %d.\n", | 327 | "tty_port_close_start: tty->count = 1 port count = %d.\n", |
305 | port->count); | 328 | port->count); |
@@ -331,12 +354,20 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f | |||
331 | long timeout; | 354 | long timeout; |
332 | 355 | ||
333 | if (bps > 1200) | 356 | if (bps > 1200) |
334 | timeout = max_t(long, (HZ * 10 * port->drain_delay) / bps, | 357 | timeout = max_t(long, |
335 | HZ / 10); | 358 | (HZ * 10 * port->drain_delay) / bps, HZ / 10); |
336 | else | 359 | else |
337 | timeout = 2 * HZ; | 360 | timeout = 2 * HZ; |
338 | schedule_timeout_interruptible(timeout); | 361 | schedule_timeout_interruptible(timeout); |
339 | } | 362 | } |
363 | /* Flush the ldisc buffering */ | ||
364 | tty_ldisc_flush(tty); | ||
365 | |||
366 | /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to | ||
367 | hang up the line */ | ||
368 | if (tty->termios->c_cflag & HUPCL) | ||
369 | tty_port_lower_dtr_rts(port); | ||
370 | |||
340 | /* Don't call port->drop for the last reference. Callers will want | 371 | /* Don't call port->drop for the last reference. Callers will want |
341 | to drop the last active reference in ->shutdown() or the tty | 372 | to drop the last active reference in ->shutdown() or the tty |
342 | shutdown path */ | 373 | shutdown path */ |
@@ -348,11 +379,6 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) | |||
348 | { | 379 | { |
349 | unsigned long flags; | 380 | unsigned long flags; |
350 | 381 | ||
351 | tty_ldisc_flush(tty); | ||
352 | |||
353 | if (tty->termios->c_cflag & HUPCL) | ||
354 | tty_port_lower_dtr_rts(port); | ||
355 | |||
356 | spin_lock_irqsave(&port->lock, flags); | 382 | spin_lock_irqsave(&port->lock, flags); |
357 | tty->closing = 0; | 383 | tty->closing = 0; |
358 | 384 | ||
@@ -377,7 +403,42 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty, | |||
377 | if (tty_port_close_start(port, tty, filp) == 0) | 403 | if (tty_port_close_start(port, tty, filp) == 0) |
378 | return; | 404 | return; |
379 | tty_port_shutdown(port); | 405 | tty_port_shutdown(port); |
406 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
380 | tty_port_close_end(port, tty); | 407 | tty_port_close_end(port, tty); |
381 | tty_port_tty_set(port, NULL); | 408 | tty_port_tty_set(port, NULL); |
382 | } | 409 | } |
383 | EXPORT_SYMBOL(tty_port_close); | 410 | EXPORT_SYMBOL(tty_port_close); |
411 | |||
412 | int tty_port_open(struct tty_port *port, struct tty_struct *tty, | ||
413 | struct file *filp) | ||
414 | { | ||
415 | spin_lock_irq(&port->lock); | ||
416 | if (!tty_hung_up_p(filp)) | ||
417 | ++port->count; | ||
418 | spin_unlock_irq(&port->lock); | ||
419 | tty_port_tty_set(port, tty); | ||
420 | |||
421 | /* | ||
422 | * Do the device-specific open only if the hardware isn't | ||
423 | * already initialized. Serialize open and shutdown using the | ||
424 | * port mutex. | ||
425 | */ | ||
426 | |||
427 | mutex_lock(&port->mutex); | ||
428 | |||
429 | if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) { | ||
430 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
431 | if (port->ops->activate) { | ||
432 | int retval = port->ops->activate(port, tty); | ||
433 | if (retval) { | ||
434 | mutex_unlock(&port->mutex); | ||
435 | return retval; | ||
436 | } | ||
437 | } | ||
438 | set_bit(ASYNCB_INITIALIZED, &port->flags); | ||
439 | } | ||
440 | mutex_unlock(&port->mutex); | ||
441 | return tty_port_block_til_ready(port, tty, filp); | ||
442 | } | ||
443 | |||
444 | EXPORT_SYMBOL(tty_port_open); | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 0c80c68cd047..50faa1fb0f06 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -161,6 +161,11 @@ static void set_palette(struct vc_data *vc); | |||
161 | static int printable; /* Is console ready for printing? */ | 161 | static int printable; /* Is console ready for printing? */ |
162 | int default_utf8 = true; | 162 | int default_utf8 = true; |
163 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); | 163 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); |
164 | int global_cursor_default = -1; | ||
165 | module_param(global_cursor_default, int, S_IRUGO | S_IWUSR); | ||
166 | |||
167 | static int cur_default = CUR_DEFAULT; | ||
168 | module_param(cur_default, int, S_IRUGO | S_IWUSR); | ||
164 | 169 | ||
165 | /* | 170 | /* |
166 | * ignore_poke: don't unblank the screen when things are typed. This is | 171 | * ignore_poke: don't unblank the screen when things are typed. This is |
@@ -182,12 +187,10 @@ static DECLARE_WORK(console_work, console_callback); | |||
182 | * fg_console is the current virtual console, | 187 | * fg_console is the current virtual console, |
183 | * last_console is the last used one, | 188 | * last_console is the last used one, |
184 | * want_console is the console we want to switch to, | 189 | * want_console is the console we want to switch to, |
185 | * kmsg_redirect is the console for kernel messages, | ||
186 | */ | 190 | */ |
187 | int fg_console; | 191 | int fg_console; |
188 | int last_console; | 192 | int last_console; |
189 | int want_console = -1; | 193 | int want_console = -1; |
190 | int kmsg_redirect; | ||
191 | 194 | ||
192 | /* | 195 | /* |
193 | * For each existing display, we have a pointer to console currently visible | 196 | * For each existing display, we have a pointer to console currently visible |
@@ -775,6 +778,12 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
775 | vc_cons[currcons].d = NULL; | 778 | vc_cons[currcons].d = NULL; |
776 | return -ENOMEM; | 779 | return -ENOMEM; |
777 | } | 780 | } |
781 | |||
782 | /* If no drivers have overridden us and the user didn't pass a | ||
783 | boot option, default to displaying the cursor */ | ||
784 | if (global_cursor_default == -1) | ||
785 | global_cursor_default = 1; | ||
786 | |||
778 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); | 787 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); |
779 | vcs_make_sysfs(currcons); | 788 | vcs_make_sysfs(currcons); |
780 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); | 789 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); |
@@ -1616,7 +1625,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
1616 | vc->vc_decscnm = 0; | 1625 | vc->vc_decscnm = 0; |
1617 | vc->vc_decom = 0; | 1626 | vc->vc_decom = 0; |
1618 | vc->vc_decawm = 1; | 1627 | vc->vc_decawm = 1; |
1619 | vc->vc_deccm = 1; | 1628 | vc->vc_deccm = global_cursor_default; |
1620 | vc->vc_decim = 0; | 1629 | vc->vc_decim = 0; |
1621 | 1630 | ||
1622 | set_kbd(vc, decarm); | 1631 | set_kbd(vc, decarm); |
@@ -1630,7 +1639,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
1630 | /* do not do set_leds here because this causes an endless tasklet loop | 1639 | /* do not do set_leds here because this causes an endless tasklet loop |
1631 | when the keyboard hasn't been initialized yet */ | 1640 | when the keyboard hasn't been initialized yet */ |
1632 | 1641 | ||
1633 | vc->vc_cursor_type = CUR_DEFAULT; | 1642 | vc->vc_cursor_type = cur_default; |
1634 | vc->vc_complement_mask = vc->vc_s_complement_mask; | 1643 | vc->vc_complement_mask = vc->vc_s_complement_mask; |
1635 | 1644 | ||
1636 | default_attr(vc); | 1645 | default_attr(vc); |
@@ -1832,7 +1841,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
1832 | if (vc->vc_par[0]) | 1841 | if (vc->vc_par[0]) |
1833 | vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16); | 1842 | vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16); |
1834 | else | 1843 | else |
1835 | vc->vc_cursor_type = CUR_DEFAULT; | 1844 | vc->vc_cursor_type = cur_default; |
1836 | return; | 1845 | return; |
1837 | } | 1846 | } |
1838 | break; | 1847 | break; |
@@ -2426,6 +2435,37 @@ struct tty_driver *console_driver; | |||
2426 | 2435 | ||
2427 | #ifdef CONFIG_VT_CONSOLE | 2436 | #ifdef CONFIG_VT_CONSOLE |
2428 | 2437 | ||
2438 | /** | ||
2439 | * vt_kmsg_redirect() - Sets/gets the kernel message console | ||
2440 | * @new: The new virtual terminal number or -1 if the console should stay | ||
2441 | * unchanged | ||
2442 | * | ||
2443 | * By default, the kernel messages are always printed on the current virtual | ||
2444 | * console. However, the user may modify that default with the | ||
2445 | * TIOCL_SETKMSGREDIRECT ioctl call. | ||
2446 | * | ||
2447 | * This function sets the kernel message console to be @new. It returns the old | ||
2448 | * virtual console number. The virtual terminal number 0 (both as parameter and | ||
2449 | * return value) means no redirection (i.e. always printed on the currently | ||
2450 | * active console). | ||
2451 | * | ||
2452 | * The parameter -1 means that only the current console is returned, but the | ||
2453 | * value is not modified. You may use the macro vt_get_kmsg_redirect() in that | ||
2454 | * case to make the code more understandable. | ||
2455 | * | ||
2456 | * When the kernel is compiled without CONFIG_VT_CONSOLE, this function ignores | ||
2457 | * the parameter and always returns 0. | ||
2458 | */ | ||
2459 | int vt_kmsg_redirect(int new) | ||
2460 | { | ||
2461 | static int kmsg_con; | ||
2462 | |||
2463 | if (new != -1) | ||
2464 | return xchg(&kmsg_con, new); | ||
2465 | else | ||
2466 | return kmsg_con; | ||
2467 | } | ||
2468 | |||
2429 | /* | 2469 | /* |
2430 | * Console on virtual terminal | 2470 | * Console on virtual terminal |
2431 | * | 2471 | * |
@@ -2440,6 +2480,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2440 | const ushort *start; | 2480 | const ushort *start; |
2441 | ushort cnt = 0; | 2481 | ushort cnt = 0; |
2442 | ushort myx; | 2482 | ushort myx; |
2483 | int kmsg_console; | ||
2443 | 2484 | ||
2444 | /* console busy or not yet initialized */ | 2485 | /* console busy or not yet initialized */ |
2445 | if (!printable) | 2486 | if (!printable) |
@@ -2447,8 +2488,9 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2447 | if (!spin_trylock(&printing_lock)) | 2488 | if (!spin_trylock(&printing_lock)) |
2448 | return; | 2489 | return; |
2449 | 2490 | ||
2450 | if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) | 2491 | kmsg_console = vt_get_kmsg_redirect(); |
2451 | vc = vc_cons[kmsg_redirect - 1].d; | 2492 | if (kmsg_console && vc_cons_allocated(kmsg_console - 1)) |
2493 | vc = vc_cons[kmsg_console - 1].d; | ||
2452 | 2494 | ||
2453 | /* read `x' only after setting currcons properly (otherwise | 2495 | /* read `x' only after setting currcons properly (otherwise |
2454 | the `x' macro will read the x of the foreground console). */ | 2496 | the `x' macro will read the x of the foreground console). */ |
@@ -2605,7 +2647,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2605 | ret = set_vesa_blanking(p); | 2647 | ret = set_vesa_blanking(p); |
2606 | break; | 2648 | break; |
2607 | case TIOCL_GETKMSGREDIRECT: | 2649 | case TIOCL_GETKMSGREDIRECT: |
2608 | data = kmsg_redirect; | 2650 | data = vt_get_kmsg_redirect(); |
2609 | ret = __put_user(data, p); | 2651 | ret = __put_user(data, p); |
2610 | break; | 2652 | break; |
2611 | case TIOCL_SETKMSGREDIRECT: | 2653 | case TIOCL_SETKMSGREDIRECT: |
@@ -2615,7 +2657,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2615 | if (get_user(data, p+1)) | 2657 | if (get_user(data, p+1)) |
2616 | ret = -EFAULT; | 2658 | ret = -EFAULT; |
2617 | else | 2659 | else |
2618 | kmsg_redirect = data; | 2660 | vt_kmsg_redirect(data); |
2619 | } | 2661 | } |
2620 | break; | 2662 | break; |
2621 | case TIOCL_GETFGCONSOLE: | 2663 | case TIOCL_GETFGCONSOLE: |
@@ -4078,6 +4120,7 @@ EXPORT_SYMBOL(fg_console); | |||
4078 | EXPORT_SYMBOL(console_blank_hook); | 4120 | EXPORT_SYMBOL(console_blank_hook); |
4079 | EXPORT_SYMBOL(console_blanked); | 4121 | EXPORT_SYMBOL(console_blanked); |
4080 | EXPORT_SYMBOL(vc_cons); | 4122 | EXPORT_SYMBOL(vc_cons); |
4123 | EXPORT_SYMBOL(global_cursor_default); | ||
4081 | #ifndef VT_SINGLE_DRIVER | 4124 | #ifndef VT_SINGLE_DRIVER |
4082 | EXPORT_SYMBOL(take_over_console); | 4125 | EXPORT_SYMBOL(take_over_console); |
4083 | EXPORT_SYMBOL(give_up_console); | 4126 | EXPORT_SYMBOL(give_up_console); |