diff options
author | Adrian Bunk <bunk@r063144.stusta.swh.mhn.de> | 2006-03-20 12:30:36 -0500 |
---|---|---|
committer | Adrian Bunk <bunk@r063144.stusta.swh.mhn.de> | 2006-03-20 12:30:36 -0500 |
commit | 0f76ee451484d02c7405d92e7bceb39b415abb01 (patch) | |
tree | 9722f84281f786ba48971dde057f5171a49969e4 /drivers/char | |
parent | 01d206a7c1167639f6ca6dac22140fbdca017558 (diff) | |
parent | 7705a8792b0fc82fd7d4dd923724606bbfd9fb20 (diff) |
Merge with git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers/char')
29 files changed, 510 insertions, 469 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 4c67727d75b1..05ba410682a3 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -222,7 +222,7 @@ config SYNCLINKMP | |||
222 | 222 | ||
223 | config SYNCLINK_GT | 223 | config SYNCLINK_GT |
224 | tristate "SyncLink GT/AC support" | 224 | tristate "SyncLink GT/AC support" |
225 | depends on SERIAL_NONSTANDARD | 225 | depends on SERIAL_NONSTANDARD && PCI |
226 | help | 226 | help |
227 | Support for SyncLink GT and SyncLink AC families of | 227 | Support for SyncLink GT and SyncLink AC families of |
228 | synchronous and asynchronous serial adapters | 228 | synchronous and asynchronous serial adapters |
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index 486ed8a11b59..a4d425d2dce2 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -15,22 +15,23 @@ config AGP | |||
15 | due to kernel allocation issues), you could use PCI accesses | 15 | due to kernel allocation issues), you could use PCI accesses |
16 | and have up to a couple gigs of texture space. | 16 | and have up to a couple gigs of texture space. |
17 | 17 | ||
18 | Note that this is the only means to have XFree4/GLX use | 18 | Note that this is the only means to have X/GLX use |
19 | write-combining with MTRR support on the AGP bus. Without it, OpenGL | 19 | write-combining with MTRR support on the AGP bus. Without it, OpenGL |
20 | direct rendering will be a lot slower but still faster than PIO. | 20 | direct rendering will be a lot slower but still faster than PIO. |
21 | 21 | ||
22 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
23 | use GLX or DRI. If unsure, say N. | ||
24 | |||
25 | To compile this driver as a module, choose M here: the | 22 | To compile this driver as a module, choose M here: the |
26 | module will be called agpgart. | 23 | module will be called agpgart. |
27 | 24 | ||
25 | You should say Y here if you want to use GLX or DRI. | ||
26 | |||
27 | If unsure, say N. | ||
28 | |||
28 | config AGP_ALI | 29 | config AGP_ALI |
29 | tristate "ALI chipset support" | 30 | tristate "ALI chipset support" |
30 | depends on AGP && X86_32 | 31 | depends on AGP && X86_32 |
31 | ---help--- | 32 | ---help--- |
32 | This option gives you AGP support for the GLX component of | 33 | This option gives you AGP support for the GLX component of |
33 | XFree86 4.x on the following ALi chipsets. The supported chipsets | 34 | X on the following ALi chipsets. The supported chipsets |
34 | include M1541, M1621, M1631, M1632, M1641,M1647,and M1651. | 35 | include M1541, M1621, M1631, M1632, M1641,M1647,and M1651. |
35 | For the ALi-chipset question, ALi suggests you refer to | 36 | For the ALi-chipset question, ALi suggests you refer to |
36 | <http://www.ali.com.tw/eng/support/index.shtml>. | 37 | <http://www.ali.com.tw/eng/support/index.shtml>. |
@@ -40,28 +41,19 @@ config AGP_ALI | |||
40 | timing issues, this chipset cannot do AGP 2x with the G200. | 41 | timing issues, this chipset cannot do AGP 2x with the G200. |
41 | This is a hardware limitation. AGP 1x seems to be fine, though. | 42 | This is a hardware limitation. AGP 1x seems to be fine, though. |
42 | 43 | ||
43 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
44 | use GLX or DRI. If unsure, say N. | ||
45 | |||
46 | config AGP_ATI | 44 | config AGP_ATI |
47 | tristate "ATI chipset support" | 45 | tristate "ATI chipset support" |
48 | depends on AGP && X86_32 | 46 | depends on AGP && X86_32 |
49 | ---help--- | 47 | ---help--- |
50 | This option gives you AGP support for the GLX component of | 48 | This option gives you AGP support for the GLX component of |
51 | XFree86 4.x on the ATI RadeonIGP family of chipsets. | 49 | X on the ATI RadeonIGP family of chipsets. |
52 | |||
53 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
54 | use GLX or DRI. If unsure, say N. | ||
55 | 50 | ||
56 | config AGP_AMD | 51 | config AGP_AMD |
57 | tristate "AMD Irongate, 761, and 762 chipset support" | 52 | tristate "AMD Irongate, 761, and 762 chipset support" |
58 | depends on AGP && X86_32 | 53 | depends on AGP && X86_32 |
59 | help | 54 | help |
60 | This option gives you AGP support for the GLX component of | 55 | This option gives you AGP support for the GLX component of |
61 | XFree86 4.x on AMD Irongate, 761, and 762 chipsets. | 56 | X on AMD Irongate, 761, and 762 chipsets. |
62 | |||
63 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
64 | use GLX or DRI. If unsure, say N. | ||
65 | 57 | ||
66 | config AGP_AMD64 | 58 | config AGP_AMD64 |
67 | tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU | 59 | tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU |
@@ -69,45 +61,38 @@ config AGP_AMD64 | |||
69 | default y if GART_IOMMU | 61 | default y if GART_IOMMU |
70 | help | 62 | help |
71 | This option gives you AGP support for the GLX component of | 63 | This option gives you AGP support for the GLX component of |
72 | XFree86 4.x using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. | 64 | X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs. |
73 | You still need an external AGP bridge like the AMD 8151, VIA | 65 | You still need an external AGP bridge like the AMD 8151, VIA |
74 | K8T400M, SiS755. It may also support other AGP bridges when loaded | 66 | K8T400M, SiS755. It may also support other AGP bridges when loaded |
75 | with agp_try_unsupported=1. | 67 | with agp_try_unsupported=1. |
76 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
77 | use GLX or DRI. If unsure, say Y | ||
78 | 68 | ||
79 | config AGP_INTEL | 69 | config AGP_INTEL |
80 | tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support" | 70 | tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support" |
81 | depends on AGP && X86 | 71 | depends on AGP && X86 |
82 | help | 72 | help |
83 | This option gives you AGP support for the GLX component of XFree86 4.x | 73 | This option gives you AGP support for the GLX component of X |
84 | on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875, | 74 | on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875, |
85 | E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G, | 75 | E7205 and E7505 chipsets and full support for the 810, 815, 830M, |
86 | 852GM, 855GM, 865G and I915 integrated graphics chipsets. | 76 | 845G, 852GM, 855GM, 865G and I915 integrated graphics chipsets. |
77 | |||
87 | 78 | ||
88 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
89 | use GLX or DRI, or if you have any Intel integrated graphics | ||
90 | chipsets. If unsure, say Y. | ||
91 | 79 | ||
92 | config AGP_NVIDIA | 80 | config AGP_NVIDIA |
93 | tristate "NVIDIA nForce/nForce2 chipset support" | 81 | tristate "NVIDIA nForce/nForce2 chipset support" |
94 | depends on AGP && X86_32 | 82 | depends on AGP && X86_32 |
95 | help | 83 | help |
96 | This option gives you AGP support for the GLX component of | 84 | This option gives you AGP support for the GLX component of |
97 | XFree86 4.x on the following NVIDIA chipsets. The supported chipsets | 85 | X on NVIDIA chipsets including nForce and nForce2 |
98 | include nForce and nForce2 | ||
99 | 86 | ||
100 | config AGP_SIS | 87 | config AGP_SIS |
101 | tristate "SiS chipset support" | 88 | tristate "SiS chipset support" |
102 | depends on AGP && X86_32 | 89 | depends on AGP && X86_32 |
103 | help | 90 | help |
104 | This option gives you AGP support for the GLX component of | 91 | This option gives you AGP support for the GLX component of |
105 | XFree86 4.x on Silicon Integrated Systems [SiS] chipsets. | 92 | X on Silicon Integrated Systems [SiS] chipsets. |
106 | 93 | ||
107 | Note that 5591/5592 AGP chipsets are NOT supported. | 94 | Note that 5591/5592 AGP chipsets are NOT supported. |
108 | 95 | ||
109 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
110 | use GLX or DRI. If unsure, say N. | ||
111 | 96 | ||
112 | config AGP_SWORKS | 97 | config AGP_SWORKS |
113 | tristate "Serverworks LE/HE chipset support" | 98 | tristate "Serverworks LE/HE chipset support" |
@@ -121,10 +106,7 @@ config AGP_VIA | |||
121 | depends on AGP && X86_32 | 106 | depends on AGP && X86_32 |
122 | help | 107 | help |
123 | This option gives you AGP support for the GLX component of | 108 | This option gives you AGP support for the GLX component of |
124 | XFree86 4.x on VIA MVP3/Apollo Pro chipsets. | 109 | X on VIA MVP3/Apollo Pro chipsets. |
125 | |||
126 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
127 | use GLX or DRI. If unsure, say N. | ||
128 | 110 | ||
129 | config AGP_I460 | 111 | config AGP_I460 |
130 | tristate "Intel 460GX chipset support" | 112 | tristate "Intel 460GX chipset support" |
@@ -159,9 +141,6 @@ config AGP_EFFICEON | |||
159 | This option gives you AGP support for the Transmeta Efficeon | 141 | This option gives you AGP support for the Transmeta Efficeon |
160 | series processors with integrated northbridges. | 142 | series processors with integrated northbridges. |
161 | 143 | ||
162 | You should say Y here if you use XFree86 3.3.6 or 4.x and want to | ||
163 | use GLX or DRI. If unsure, say Y. | ||
164 | |||
165 | config AGP_SGI_TIOCA | 144 | config AGP_SGI_TIOCA |
166 | tristate "SGI TIO chipset AGP support" | 145 | tristate "SGI TIO chipset AGP support" |
167 | depends on AGP && (IA64_SGI_SN2 || IA64_GENERIC) | 146 | depends on AGP && (IA64_SGI_SN2 || IA64_GENERIC) |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 9964c508c111..1251b2515bbe 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -516,8 +516,10 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) | |||
516 | pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase); | 516 | pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase); |
517 | 517 | ||
518 | /* if x86-64 aperture base is beyond 4G, exit here */ | 518 | /* if x86-64 aperture base is beyond 4G, exit here */ |
519 | if ( (apbase & 0x7fff) >> (32 - 25) ) | 519 | if ( (apbase & 0x7fff) >> (32 - 25) ) { |
520 | return -ENODEV; | 520 | printk(KERN_INFO PFX "aperture base > 4G\n"); |
521 | return -ENODEV; | ||
522 | } | ||
521 | 523 | ||
522 | apbase = (apbase & 0x7fff) << 25; | 524 | apbase = (apbase & 0x7fff) << 25; |
523 | 525 | ||
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 268f78d926d3..efef9999f1cf 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -468,9 +468,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, | |||
468 | 468 | ||
469 | switch (pdev->device) { | 469 | switch (pdev->device) { |
470 | case 0x0006: | 470 | case 0x0006: |
471 | /* ServerWorks CNB20HE | 471 | printk (KERN_ERR PFX "ServerWorks CNB20HE is unsupported due to lack of documentation.\n"); |
472 | Fail silently.*/ | ||
473 | printk (KERN_ERR PFX "Detected ServerWorks CNB20HE chipset: No AGP present.\n"); | ||
474 | return -ENODEV; | 472 | return -ENODEV; |
475 | 473 | ||
476 | case PCI_DEVICE_ID_SERVERWORKS_HE: | 474 | case PCI_DEVICE_ID_SERVERWORKS_HE: |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 71b8b32b075f..107df9fdba4e 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -980,7 +980,7 @@ extern int drm_put_head(drm_head_t * head); | |||
980 | extern unsigned int drm_debug; | 980 | extern unsigned int drm_debug; |
981 | extern unsigned int drm_cards_limit; | 981 | extern unsigned int drm_cards_limit; |
982 | extern drm_head_t **drm_heads; | 982 | extern drm_head_t **drm_heads; |
983 | extern struct drm_sysfs_class *drm_class; | 983 | extern struct class *drm_class; |
984 | extern struct proc_dir_entry *drm_proc_root; | 984 | extern struct proc_dir_entry *drm_proc_root; |
985 | 985 | ||
986 | /* Proc support (drm_proc.h) */ | 986 | /* Proc support (drm_proc.h) */ |
@@ -1011,11 +1011,9 @@ extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); | |||
1011 | extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); | 1011 | extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); |
1012 | 1012 | ||
1013 | /* sysfs support (drm_sysfs.c) */ | 1013 | /* sysfs support (drm_sysfs.c) */ |
1014 | struct drm_sysfs_class; | 1014 | extern struct class *drm_sysfs_create(struct module *owner, char *name); |
1015 | extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner, | 1015 | extern void drm_sysfs_destroy(struct class *cs); |
1016 | char *name); | 1016 | extern struct class_device *drm_sysfs_device_add(struct class *cs, |
1017 | extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); | ||
1018 | extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | ||
1019 | drm_head_t *head); | 1017 | drm_head_t *head); |
1020 | extern void drm_sysfs_device_remove(struct class_device *class_dev); | 1018 | extern void drm_sysfs_device_remove(struct class_device *class_dev); |
1021 | 1019 | ||
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 8fd6357a48da..2c17e88a8847 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
@@ -85,7 +85,6 @@ | |||
85 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ | 85 | {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ |
86 | {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 86 | {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
87 | {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 87 | {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
88 | {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ | ||
89 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ | 88 | {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ |
90 | {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ | 89 | {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ |
91 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ | 90 | {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 7a9263ff3007..68073e14fdec 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444); | |||
50 | module_param_named(debug, drm_debug, int, 0600); | 50 | module_param_named(debug, drm_debug, int, 0600); |
51 | 51 | ||
52 | drm_head_t **drm_heads; | 52 | drm_head_t **drm_heads; |
53 | struct drm_sysfs_class *drm_class; | 53 | struct class *drm_class; |
54 | struct proc_dir_entry *drm_proc_root; | 54 | struct proc_dir_entry *drm_proc_root; |
55 | 55 | ||
56 | static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, | 56 | static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, |
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 68e43ddc16ae..0b9f98a7eb10 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support | 3 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support |
3 | * extra sysfs attribute from DRM. Normal drm_sysfs_class | 4 | * extra sysfs attribute from DRM. Normal drm_sysfs_class |
@@ -19,36 +20,6 @@ | |||
19 | #include "drm_core.h" | 20 | #include "drm_core.h" |
20 | #include "drmP.h" | 21 | #include "drmP.h" |
21 | 22 | ||
22 | struct drm_sysfs_class { | ||
23 | struct class_device_attribute attr; | ||
24 | struct class class; | ||
25 | }; | ||
26 | #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) | ||
27 | |||
28 | struct simple_dev { | ||
29 | dev_t dev; | ||
30 | struct class_device class_dev; | ||
31 | }; | ||
32 | #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) | ||
33 | |||
34 | static void release_simple_dev(struct class_device *class_dev) | ||
35 | { | ||
36 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
37 | kfree(s_dev); | ||
38 | } | ||
39 | |||
40 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | ||
41 | { | ||
42 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
43 | return print_dev_t(buf, s_dev->dev); | ||
44 | } | ||
45 | |||
46 | static void drm_sysfs_class_release(struct class *class) | ||
47 | { | ||
48 | struct drm_sysfs_class *cs = to_drm_sysfs_class(class); | ||
49 | kfree(cs); | ||
50 | } | ||
51 | |||
52 | /* Display the version of drm_core. This doesn't work right in current design */ | 23 | /* Display the version of drm_core. This doesn't work right in current design */ |
53 | static ssize_t version_show(struct class *dev, char *buf) | 24 | static ssize_t version_show(struct class *dev, char *buf) |
54 | { | 25 | { |
@@ -69,38 +40,16 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL); | |||
69 | * Note, the pointer created here is to be destroyed when finished by making a | 40 | * Note, the pointer created here is to be destroyed when finished by making a |
70 | * call to drm_sysfs_destroy(). | 41 | * call to drm_sysfs_destroy(). |
71 | */ | 42 | */ |
72 | struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) | 43 | struct class *drm_sysfs_create(struct module *owner, char *name) |
73 | { | 44 | { |
74 | struct drm_sysfs_class *cs; | 45 | struct class *class; |
75 | int retval; | 46 | |
76 | 47 | class = class_create(owner, name); | |
77 | cs = kmalloc(sizeof(*cs), GFP_KERNEL); | 48 | if (!class) |
78 | if (!cs) { | 49 | return class; |
79 | retval = -ENOMEM; | 50 | |
80 | goto error; | 51 | class_create_file(class, &class_attr_version); |
81 | } | 52 | return class; |
82 | memset(cs, 0x00, sizeof(*cs)); | ||
83 | |||
84 | cs->class.name = name; | ||
85 | cs->class.class_release = drm_sysfs_class_release; | ||
86 | cs->class.release = release_simple_dev; | ||
87 | |||
88 | cs->attr.attr.name = "dev"; | ||
89 | cs->attr.attr.mode = S_IRUGO; | ||
90 | cs->attr.attr.owner = owner; | ||
91 | cs->attr.show = show_dev; | ||
92 | cs->attr.store = NULL; | ||
93 | |||
94 | retval = class_register(&cs->class); | ||
95 | if (retval) | ||
96 | goto error; | ||
97 | class_create_file(&cs->class, &class_attr_version); | ||
98 | |||
99 | return cs; | ||
100 | |||
101 | error: | ||
102 | kfree(cs); | ||
103 | return ERR_PTR(retval); | ||
104 | } | 53 | } |
105 | 54 | ||
106 | /** | 55 | /** |
@@ -110,12 +59,13 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) | |||
110 | * Note, the pointer to be destroyed must have been created with a call to | 59 | * Note, the pointer to be destroyed must have been created with a call to |
111 | * drm_sysfs_create(). | 60 | * drm_sysfs_create(). |
112 | */ | 61 | */ |
113 | void drm_sysfs_destroy(struct drm_sysfs_class *cs) | 62 | void drm_sysfs_destroy(struct class *class) |
114 | { | 63 | { |
115 | if ((cs == NULL) || (IS_ERR(cs))) | 64 | if ((class == NULL) || (IS_ERR(class))) |
116 | return; | 65 | return; |
117 | 66 | ||
118 | class_unregister(&cs->class); | 67 | class_remove_file(class, &class_attr_version); |
68 | class_destroy(class); | ||
119 | } | 69 | } |
120 | 70 | ||
121 | static ssize_t show_dri(struct class_device *class_device, char *buf) | 71 | static ssize_t show_dri(struct class_device *class_device, char *buf) |
@@ -132,7 +82,7 @@ static struct class_device_attribute class_device_attrs[] = { | |||
132 | 82 | ||
133 | /** | 83 | /** |
134 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver | 84 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver |
135 | * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. | 85 | * @cs: pointer to the struct class that this device should be registered to. |
136 | * @dev: the dev_t for the device to be added. | 86 | * @dev: the dev_t for the device to be added. |
137 | * @device: a pointer to a struct device that is assiociated with this class device. | 87 | * @device: a pointer to a struct device that is assiociated with this class device. |
138 | * @fmt: string for the class device's name | 88 | * @fmt: string for the class device's name |
@@ -141,46 +91,26 @@ static struct class_device_attribute class_device_attrs[] = { | |||
141 | * class. A "dev" file will be created, showing the dev_t for the device. The | 91 | * class. A "dev" file will be created, showing the dev_t for the device. The |
142 | * pointer to the struct class_device will be returned from the call. Any further | 92 | * pointer to the struct class_device will be returned from the call. Any further |
143 | * sysfs files that might be required can be created using this pointer. | 93 | * sysfs files that might be required can be created using this pointer. |
144 | * Note: the struct drm_sysfs_class passed to this function must have previously been | 94 | * Note: the struct class passed to this function must have previously been |
145 | * created with a call to drm_sysfs_create(). | 95 | * created with a call to drm_sysfs_create(). |
146 | */ | 96 | */ |
147 | struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | 97 | struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) |
148 | drm_head_t *head) | ||
149 | { | 98 | { |
150 | struct simple_dev *s_dev = NULL; | 99 | struct class_device *class_dev; |
151 | int i, retval; | 100 | int i; |
152 | |||
153 | if ((cs == NULL) || (IS_ERR(cs))) { | ||
154 | retval = -ENODEV; | ||
155 | goto error; | ||
156 | } | ||
157 | |||
158 | s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL); | ||
159 | if (!s_dev) { | ||
160 | retval = -ENOMEM; | ||
161 | goto error; | ||
162 | } | ||
163 | memset(s_dev, 0x00, sizeof(*s_dev)); | ||
164 | |||
165 | s_dev->dev = MKDEV(DRM_MAJOR, head->minor); | ||
166 | s_dev->class_dev.dev = &(head->dev->pdev)->dev; | ||
167 | s_dev->class_dev.class = &cs->class; | ||
168 | 101 | ||
169 | snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor); | 102 | class_dev = class_device_create(cs, NULL, |
170 | retval = class_device_register(&s_dev->class_dev); | 103 | MKDEV(DRM_MAJOR, head->minor), |
171 | if (retval) | 104 | &(head->dev->pdev)->dev, |
172 | goto error; | 105 | "card%d", head->minor); |
106 | if (!class_dev) | ||
107 | return NULL; | ||
173 | 108 | ||
174 | class_device_create_file(&s_dev->class_dev, &cs->attr); | 109 | class_set_devdata(class_dev, head); |
175 | class_set_devdata(&s_dev->class_dev, head); | ||
176 | 110 | ||
177 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 111 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
178 | class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); | 112 | class_device_create_file(class_dev, &class_device_attrs[i]); |
179 | return &s_dev->class_dev; | 113 | return class_dev; |
180 | |||
181 | error: | ||
182 | kfree(s_dev); | ||
183 | return ERR_PTR(retval); | ||
184 | } | 114 | } |
185 | 115 | ||
186 | /** | 116 | /** |
@@ -192,10 +122,9 @@ error: | |||
192 | */ | 122 | */ |
193 | void drm_sysfs_device_remove(struct class_device *class_dev) | 123 | void drm_sysfs_device_remove(struct class_device *class_dev) |
194 | { | 124 | { |
195 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
196 | int i; | 125 | int i; |
197 | 126 | ||
198 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 127 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
199 | class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]); | 128 | class_device_remove_file(class_dev, &class_device_attrs[i]); |
200 | class_device_unregister(&s_dev->class_dev); | 129 | class_device_unregister(class_dev); |
201 | } | 130 | } |
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c index a1381c61aa63..d3879ac9970f 100644 --- a/drivers/char/drm/i915_irq.c +++ b/drivers/char/drm/i915_irq.c | |||
@@ -202,10 +202,15 @@ void i915_driver_irq_postinstall(drm_device_t * dev) | |||
202 | void i915_driver_irq_uninstall(drm_device_t * dev) | 202 | void i915_driver_irq_uninstall(drm_device_t * dev) |
203 | { | 203 | { |
204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
205 | u16 temp; | ||
206 | |||
205 | if (!dev_priv) | 207 | if (!dev_priv) |
206 | return; | 208 | return; |
207 | 209 | ||
208 | I915_WRITE16(I915REG_HWSTAM, 0xffff); | 210 | I915_WRITE16(I915REG_HWSTAM, 0xffff); |
209 | I915_WRITE16(I915REG_INT_MASK_R, 0xffff); | 211 | I915_WRITE16(I915REG_INT_MASK_R, 0xffff); |
210 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); | 212 | I915_WRITE16(I915REG_INT_ENABLE_R, 0x0); |
213 | |||
214 | temp = I915_READ16(I915REG_INT_IDENTITY_R); | ||
215 | I915_WRITE16(I915REG_INT_IDENTITY_R, temp); | ||
211 | } | 216 | } |
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index 291dbf4c8186..c08fa5076f05 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
@@ -161,6 +161,7 @@ void r300_init_reg_flags(void) | |||
161 | ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); | 161 | ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); |
162 | ADD_RANGE(R300_GB_ENABLE, 1); | 162 | ADD_RANGE(R300_GB_ENABLE, 1); |
163 | ADD_RANGE(R300_GB_MSPOS0, 5); | 163 | ADD_RANGE(R300_GB_MSPOS0, 5); |
164 | ADD_RANGE(R300_TX_CNTL, 1); | ||
164 | ADD_RANGE(R300_TX_ENABLE, 1); | 165 | ADD_RANGE(R300_TX_ENABLE, 1); |
165 | ADD_RANGE(0x4200, 4); | 166 | ADD_RANGE(0x4200, 4); |
166 | ADD_RANGE(0x4214, 1); | 167 | ADD_RANGE(0x4214, 1); |
@@ -489,6 +490,50 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, | |||
489 | 490 | ||
490 | return 0; | 491 | return 0; |
491 | } | 492 | } |
493 | static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, | ||
494 | drm_radeon_kcmd_buffer_t *cmdbuf) | ||
495 | { | ||
496 | u32 *cmd = (u32 *) cmdbuf->buf; | ||
497 | int count, ret; | ||
498 | RING_LOCALS; | ||
499 | |||
500 | count=(cmd[0]>>16) & 0x3fff; | ||
501 | |||
502 | if (cmd[0] & 0x8000) { | ||
503 | u32 offset; | ||
504 | |||
505 | if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL | ||
506 | | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | ||
507 | offset = cmd[2] << 10; | ||
508 | ret = r300_check_offset(dev_priv, offset); | ||
509 | if (ret) { | ||
510 | DRM_ERROR("Invalid bitblt first offset is %08X\n", offset); | ||
511 | return DRM_ERR(EINVAL); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) && | ||
516 | (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) { | ||
517 | offset = cmd[3] << 10; | ||
518 | ret = r300_check_offset(dev_priv, offset); | ||
519 | if (ret) { | ||
520 | DRM_ERROR("Invalid bitblt second offset is %08X\n", offset); | ||
521 | return DRM_ERR(EINVAL); | ||
522 | } | ||
523 | |||
524 | } | ||
525 | } | ||
526 | |||
527 | BEGIN_RING(count+2); | ||
528 | OUT_RING(cmd[0]); | ||
529 | OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1); | ||
530 | ADVANCE_RING(); | ||
531 | |||
532 | cmdbuf->buf += (count+2)*4; | ||
533 | cmdbuf->bufsz -= (count+2)*4; | ||
534 | |||
535 | return 0; | ||
536 | } | ||
492 | 537 | ||
493 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, | 538 | static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, |
494 | drm_radeon_kcmd_buffer_t *cmdbuf) | 539 | drm_radeon_kcmd_buffer_t *cmdbuf) |
@@ -527,6 +572,9 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv, | |||
527 | case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ | 572 | case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */ |
528 | return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header); | 573 | return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header); |
529 | 574 | ||
575 | case RADEON_CNTL_BITBLT_MULTI: | ||
576 | return r300_emit_bitblt_multi(dev_priv, cmdbuf); | ||
577 | |||
530 | case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ | 578 | case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ |
531 | case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ | 579 | case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ |
532 | case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ | 580 | case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ |
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h index a0ed20e25221..d1e19954406b 100644 --- a/drivers/char/drm/r300_reg.h +++ b/drivers/char/drm/r300_reg.h | |||
@@ -451,6 +451,9 @@ I am fairly certain that they are correct unless stated otherwise in comments. | |||
451 | /* END */ | 451 | /* END */ |
452 | 452 | ||
453 | /* gap */ | 453 | /* gap */ |
454 | /* Zero to flush caches. */ | ||
455 | #define R300_TX_CNTL 0x4100 | ||
456 | |||
454 | /* The upper enable bits are guessed, based on fglrx reported limits. */ | 457 | /* The upper enable bits are guessed, based on fglrx reported limits. */ |
455 | #define R300_TX_ENABLE 0x4104 | 458 | #define R300_TX_ENABLE 0x4104 |
456 | # define R300_TX_ENABLE_0 (1 << 0) | 459 | # define R300_TX_ENABLE_0 (1 << 0) |
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h index 498b19b1d641..1f7d2ab8c4fc 100644 --- a/drivers/char/drm/radeon_drv.h +++ b/drivers/char/drm/radeon_drv.h | |||
@@ -90,9 +90,10 @@ | |||
90 | * 1.19- Add support for gart table in FB memory and PCIE r300 | 90 | * 1.19- Add support for gart table in FB memory and PCIE r300 |
91 | * 1.20- Add support for r300 texrect | 91 | * 1.20- Add support for r300 texrect |
92 | * 1.21- Add support for card type getparam | 92 | * 1.21- Add support for card type getparam |
93 | * 1.22- Add support for texture cache flushes (R300_TX_CNTL) | ||
93 | */ | 94 | */ |
94 | #define DRIVER_MAJOR 1 | 95 | #define DRIVER_MAJOR 1 |
95 | #define DRIVER_MINOR 21 | 96 | #define DRIVER_MINOR 22 |
96 | #define DRIVER_PATCHLEVEL 0 | 97 | #define DRIVER_PATCHLEVEL 0 |
97 | 98 | ||
98 | /* | 99 | /* |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 57539d8f9f7c..09dc4b01232c 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -150,17 +150,6 @@ static void rs_wait_until_sent(struct tty_struct *, int); | |||
150 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ | 150 | /* Standard COM flags (except for COM4, because of the 8514 problem) */ |
151 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | 151 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) |
152 | 152 | ||
153 | /* | ||
154 | * tmp_buf is used as a temporary buffer by serial_write. We need to | ||
155 | * lock it in case the memcpy_fromfs blocks while swapping in a page, | ||
156 | * and some other program tries to do a serial write at the same time. | ||
157 | * Since the lock will only come under contention when the system is | ||
158 | * swapping and available memory is low, it makes sense to share one | ||
159 | * buffer across all the serial ports, since it significantly saves | ||
160 | * memory if large numbers of serial ports are open. | ||
161 | */ | ||
162 | static unsigned char *tmp_buf; | ||
163 | |||
164 | static inline int serial_paranoia_check(struct esp_struct *info, | 153 | static inline int serial_paranoia_check(struct esp_struct *info, |
165 | char *name, const char *routine) | 154 | char *name, const char *routine) |
166 | { | 155 | { |
@@ -1267,7 +1256,7 @@ static int rs_write(struct tty_struct * tty, | |||
1267 | if (serial_paranoia_check(info, tty->name, "rs_write")) | 1256 | if (serial_paranoia_check(info, tty->name, "rs_write")) |
1268 | return 0; | 1257 | return 0; |
1269 | 1258 | ||
1270 | if (!tty || !info->xmit_buf || !tmp_buf) | 1259 | if (!tty || !info->xmit_buf) |
1271 | return 0; | 1260 | return 0; |
1272 | 1261 | ||
1273 | while (1) { | 1262 | while (1) { |
@@ -2291,11 +2280,7 @@ static int esp_open(struct tty_struct *tty, struct file * filp) | |||
2291 | tty->driver_data = info; | 2280 | tty->driver_data = info; |
2292 | info->tty = tty; | 2281 | info->tty = tty; |
2293 | 2282 | ||
2294 | if (!tmp_buf) { | 2283 | spin_unlock_irqrestore(&info->lock, flags); |
2295 | tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL); | ||
2296 | if (!tmp_buf) | ||
2297 | return -ENOMEM; | ||
2298 | } | ||
2299 | 2284 | ||
2300 | /* | 2285 | /* |
2301 | * Start up serial port | 2286 | * Start up serial port |
@@ -2602,9 +2587,6 @@ static void __exit espserial_exit(void) | |||
2602 | free_pages((unsigned long)dma_buffer, | 2587 | free_pages((unsigned long)dma_buffer, |
2603 | get_order(DMA_BUFFER_SZ)); | 2588 | get_order(DMA_BUFFER_SZ)); |
2604 | 2589 | ||
2605 | if (tmp_buf) | ||
2606 | free_page((unsigned long)tmp_buf); | ||
2607 | |||
2608 | while (free_pio_buf) { | 2590 | while (free_pio_buf) { |
2609 | pio_buf = free_pio_buf->next; | 2591 | pio_buf = free_pio_buf->next; |
2610 | kfree(free_pio_buf); | 2592 | kfree(free_pio_buf); |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 66a2fee06eb9..ef140ebde117 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -956,22 +956,18 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) | |||
956 | } | 956 | } |
957 | } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { | 957 | } else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) { |
958 | struct acpi_resource_extended_irq *irqp; | 958 | struct acpi_resource_extended_irq *irqp; |
959 | int i; | 959 | int i, irq; |
960 | 960 | ||
961 | irqp = &res->data.extended_irq; | 961 | irqp = &res->data.extended_irq; |
962 | 962 | ||
963 | if (irqp->interrupt_count > 0) { | 963 | for (i = 0; i < irqp->interrupt_count; i++) { |
964 | hdp->hd_nirqs = irqp->interrupt_count; | 964 | irq = acpi_register_gsi(irqp->interrupts[i], |
965 | 965 | irqp->triggering, irqp->polarity); | |
966 | for (i = 0; i < hdp->hd_nirqs; i++) { | 966 | if (irq < 0) |
967 | int rc = | 967 | return AE_ERROR; |
968 | acpi_register_gsi(irqp->interrupts[i], | 968 | |
969 | irqp->triggering, | 969 | hdp->hd_irq[hdp->hd_nirqs] = irq; |
970 | irqp->polarity); | 970 | hdp->hd_nirqs++; |
971 | if (rc < 0) | ||
972 | return AE_ERROR; | ||
973 | hdp->hd_irq[i] = rc; | ||
974 | } | ||
975 | } | 971 | } |
976 | } | 972 | } |
977 | 973 | ||
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 1994a92d4733..f65b2e14a485 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -335,6 +335,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
335 | } /* else count == 0 */ | 335 | } /* else count == 0 */ |
336 | 336 | ||
337 | tty->driver_data = hp; | 337 | tty->driver_data = hp; |
338 | tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ | ||
339 | |||
338 | hp->tty = tty; | 340 | hp->tty = tty; |
339 | /* Save for request_irq outside of spin_lock. */ | 341 | /* Save for request_irq outside of spin_lock. */ |
340 | irq = hp->irq; | 342 | irq = hp->irq; |
@@ -633,9 +635,6 @@ static int hvc_poll(struct hvc_struct *hp) | |||
633 | tty_insert_flip_char(tty, buf[i], 0); | 635 | tty_insert_flip_char(tty, buf[i], 0); |
634 | } | 636 | } |
635 | 637 | ||
636 | if (count) | ||
637 | tty_schedule_flip(tty); | ||
638 | |||
639 | /* | 638 | /* |
640 | * Account for the total amount read in one loop, and if above | 639 | * Account for the total amount read in one loop, and if above |
641 | * 64 bytes, we do a quick schedule loop to let the tty grok | 640 | * 64 bytes, we do a quick schedule loop to let the tty grok |
@@ -656,6 +655,9 @@ static int hvc_poll(struct hvc_struct *hp) | |||
656 | bail: | 655 | bail: |
657 | spin_unlock_irqrestore(&hp->lock, flags); | 656 | spin_unlock_irqrestore(&hp->lock, flags); |
658 | 657 | ||
658 | if (read_total) | ||
659 | tty_flip_buffer_push(tty); | ||
660 | |||
659 | return poll_mask; | 661 | return poll_mask; |
660 | } | 662 | } |
661 | 663 | ||
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c index b3bc2e37e616..29dc87e59020 100644 --- a/drivers/char/hw_random.c +++ b/drivers/char/hw_random.c | |||
@@ -131,7 +131,9 @@ enum { | |||
131 | rng_hw_none, | 131 | rng_hw_none, |
132 | rng_hw_intel, | 132 | rng_hw_intel, |
133 | rng_hw_amd, | 133 | rng_hw_amd, |
134 | #ifdef __i386__ | ||
134 | rng_hw_via, | 135 | rng_hw_via, |
136 | #endif | ||
135 | rng_hw_geode, | 137 | rng_hw_geode, |
136 | }; | 138 | }; |
137 | 139 | ||
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index c92378121b4c..1b05fa688996 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -675,7 +675,7 @@ static int __init mmtimer_init(void) | |||
675 | cnodeid_t node, maxn = -1; | 675 | cnodeid_t node, maxn = -1; |
676 | 676 | ||
677 | if (!ia64_platform_is("sn2")) | 677 | if (!ia64_platform_is("sn2")) |
678 | return -1; | 678 | return 0; |
679 | 679 | ||
680 | /* | 680 | /* |
681 | * Sanity check the cycles/sec variable | 681 | * Sanity check the cycles/sec variable |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 649677b5dc36..5fdf18515433 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -13,11 +13,12 @@ | |||
13 | * | 13 | * |
14 | * (C) 2000,2001,2002,2003,2004 Omnikey AG | 14 | * (C) 2000,2001,2002,2003,2004 Omnikey AG |
15 | * | 15 | * |
16 | * (C) 2005 Harald Welte <laforge@gnumonks.org> | 16 | * (C) 2005-2006 Harald Welte <laforge@gnumonks.org> |
17 | * - Adhere to Kernel CodingStyle | 17 | * - Adhere to Kernel CodingStyle |
18 | * - Port to 2.6.13 "new" style PCMCIA | 18 | * - Port to 2.6.13 "new" style PCMCIA |
19 | * - Check for copy_{from,to}_user return values | 19 | * - Check for copy_{from,to}_user return values |
20 | * - Use nonseekable_open() | 20 | * - Use nonseekable_open() |
21 | * - add class interface for udev device creation | ||
21 | * | 22 | * |
22 | * All rights reserved. Licensed under dual BSD/GPL license. | 23 | * All rights reserved. Licensed under dual BSD/GPL license. |
23 | */ | 24 | */ |
@@ -56,7 +57,7 @@ module_param(pc_debug, int, 0600); | |||
56 | #else | 57 | #else |
57 | #define DEBUGP(n, rdr, x, args...) | 58 | #define DEBUGP(n, rdr, x, args...) |
58 | #endif | 59 | #endif |
59 | static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte"; | 60 | static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte"; |
60 | 61 | ||
61 | #define T_1SEC (HZ) | 62 | #define T_1SEC (HZ) |
62 | #define T_10MSEC msecs_to_jiffies(10) | 63 | #define T_10MSEC msecs_to_jiffies(10) |
@@ -156,6 +157,7 @@ struct cm4000_dev { | |||
156 | /*queue*/ 4*sizeof(wait_queue_head_t)) | 157 | /*queue*/ 4*sizeof(wait_queue_head_t)) |
157 | 158 | ||
158 | static dev_link_t *dev_table[CM4000_MAX_DEV]; | 159 | static dev_link_t *dev_table[CM4000_MAX_DEV]; |
160 | static struct class *cmm_class; | ||
159 | 161 | ||
160 | /* This table doesn't use spaces after the comma between fields and thus | 162 | /* This table doesn't use spaces after the comma between fields and thus |
161 | * violates CodingStyle. However, I don't really think wrapping it around will | 163 | * violates CodingStyle. However, I don't really think wrapping it around will |
@@ -1937,6 +1939,9 @@ static int cm4000_attach(struct pcmcia_device *p_dev) | |||
1937 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 1939 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
1938 | cm4000_config(link, i); | 1940 | cm4000_config(link, i); |
1939 | 1941 | ||
1942 | class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, | ||
1943 | "cmm%d", i); | ||
1944 | |||
1940 | return 0; | 1945 | return 0; |
1941 | } | 1946 | } |
1942 | 1947 | ||
@@ -1962,6 +1967,8 @@ static void cm4000_detach(struct pcmcia_device *p_dev) | |||
1962 | dev_table[devno] = NULL; | 1967 | dev_table[devno] = NULL; |
1963 | kfree(dev); | 1968 | kfree(dev); |
1964 | 1969 | ||
1970 | class_device_destroy(cmm_class, MKDEV(major, devno)); | ||
1971 | |||
1965 | return; | 1972 | return; |
1966 | } | 1973 | } |
1967 | 1974 | ||
@@ -1995,8 +2002,18 @@ static struct pcmcia_driver cm4000_driver = { | |||
1995 | 2002 | ||
1996 | static int __init cmm_init(void) | 2003 | static int __init cmm_init(void) |
1997 | { | 2004 | { |
2005 | int rc; | ||
2006 | |||
1998 | printk(KERN_INFO "%s\n", version); | 2007 | printk(KERN_INFO "%s\n", version); |
1999 | pcmcia_register_driver(&cm4000_driver); | 2008 | |
2009 | cmm_class = class_create(THIS_MODULE, "cardman_4000"); | ||
2010 | if (!cmm_class) | ||
2011 | return -1; | ||
2012 | |||
2013 | rc = pcmcia_register_driver(&cm4000_driver); | ||
2014 | if (rc < 0) | ||
2015 | return rc; | ||
2016 | |||
2000 | major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); | 2017 | major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); |
2001 | if (major < 0) { | 2018 | if (major < 0) { |
2002 | printk(KERN_WARNING MODULE_NAME | 2019 | printk(KERN_WARNING MODULE_NAME |
@@ -2012,6 +2029,7 @@ static void __exit cmm_exit(void) | |||
2012 | printk(KERN_INFO MODULE_NAME ": unloading\n"); | 2029 | printk(KERN_INFO MODULE_NAME ": unloading\n"); |
2013 | pcmcia_unregister_driver(&cm4000_driver); | 2030 | pcmcia_unregister_driver(&cm4000_driver); |
2014 | unregister_chrdev(major, DEVICE_NAME); | 2031 | unregister_chrdev(major, DEVICE_NAME); |
2032 | class_destroy(cmm_class); | ||
2015 | }; | 2033 | }; |
2016 | 2034 | ||
2017 | module_init(cmm_init); | 2035 | module_init(cmm_init); |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 46eb371bf17e..466e33bab029 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -3,12 +3,13 @@ | |||
3 | * | 3 | * |
4 | * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/) | 4 | * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/) |
5 | * | 5 | * |
6 | * (C) 2005 Harald Welte <laforge@gnumonks.org> | 6 | * (C) 2005-2006 Harald Welte <laforge@gnumonks.org> |
7 | * - add support for poll() | 7 | * - add support for poll() |
8 | * - driver cleanup | 8 | * - driver cleanup |
9 | * - add waitqueues | 9 | * - add waitqueues |
10 | * - adhere to linux kernel coding style and policies | 10 | * - adhere to linux kernel coding style and policies |
11 | * - support 2.6.13 "new style" pcmcia interface | 11 | * - support 2.6.13 "new style" pcmcia interface |
12 | * - add class interface for udev device creation | ||
12 | * | 13 | * |
13 | * The device basically is a USB CCID compliant device that has been | 14 | * The device basically is a USB CCID compliant device that has been |
14 | * attached to an I/O-Mapped FIFO. | 15 | * attached to an I/O-Mapped FIFO. |
@@ -53,7 +54,7 @@ module_param(pc_debug, int, 0600); | |||
53 | #endif | 54 | #endif |
54 | 55 | ||
55 | static char *version = | 56 | static char *version = |
56 | "OMNIKEY CardMan 4040 v1.1.0gm4 - All bugs added by Harald Welte"; | 57 | "OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte"; |
57 | 58 | ||
58 | #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) | 59 | #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) |
59 | #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) | 60 | #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) |
@@ -67,6 +68,7 @@ static char *version = | |||
67 | static void reader_release(dev_link_t *link); | 68 | static void reader_release(dev_link_t *link); |
68 | 69 | ||
69 | static int major; | 70 | static int major; |
71 | static struct class *cmx_class; | ||
70 | 72 | ||
71 | #define BS_READABLE 0x01 | 73 | #define BS_READABLE 0x01 |
72 | #define BS_WRITABLE 0x02 | 74 | #define BS_WRITABLE 0x02 |
@@ -696,6 +698,9 @@ static int reader_attach(struct pcmcia_device *p_dev) | |||
696 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 698 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
697 | reader_config(link, i); | 699 | reader_config(link, i); |
698 | 700 | ||
701 | class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, | ||
702 | "cmx%d", i); | ||
703 | |||
699 | return 0; | 704 | return 0; |
700 | } | 705 | } |
701 | 706 | ||
@@ -721,6 +726,8 @@ static void reader_detach(struct pcmcia_device *p_dev) | |||
721 | dev_table[devno] = NULL; | 726 | dev_table[devno] = NULL; |
722 | kfree(dev); | 727 | kfree(dev); |
723 | 728 | ||
729 | class_device_destroy(cmx_class, MKDEV(major, devno)); | ||
730 | |||
724 | return; | 731 | return; |
725 | } | 732 | } |
726 | 733 | ||
@@ -755,8 +762,17 @@ static struct pcmcia_driver reader_driver = { | |||
755 | 762 | ||
756 | static int __init cm4040_init(void) | 763 | static int __init cm4040_init(void) |
757 | { | 764 | { |
765 | int rc; | ||
766 | |||
758 | printk(KERN_INFO "%s\n", version); | 767 | printk(KERN_INFO "%s\n", version); |
759 | pcmcia_register_driver(&reader_driver); | 768 | cmx_class = class_create(THIS_MODULE, "cardman_4040"); |
769 | if (!cmx_class) | ||
770 | return -1; | ||
771 | |||
772 | rc = pcmcia_register_driver(&reader_driver); | ||
773 | if (rc < 0) | ||
774 | return rc; | ||
775 | |||
760 | major = register_chrdev(0, DEVICE_NAME, &reader_fops); | 776 | major = register_chrdev(0, DEVICE_NAME, &reader_fops); |
761 | if (major < 0) { | 777 | if (major < 0) { |
762 | printk(KERN_WARNING MODULE_NAME | 778 | printk(KERN_WARNING MODULE_NAME |
@@ -771,6 +787,7 @@ static void __exit cm4040_exit(void) | |||
771 | printk(KERN_INFO MODULE_NAME ": unloading\n"); | 787 | printk(KERN_INFO MODULE_NAME ": unloading\n"); |
772 | pcmcia_unregister_driver(&reader_driver); | 788 | pcmcia_unregister_driver(&reader_driver); |
773 | unregister_chrdev(major, DEVICE_NAME); | 789 | unregister_chrdev(major, DEVICE_NAME); |
790 | class_destroy(cmx_class); | ||
774 | } | 791 | } |
775 | 792 | ||
776 | module_init(cm4040_init); | 793 | module_init(cm4040_init); |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 80a5b840e22f..fee68cc895f8 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -103,6 +103,7 @@ | |||
103 | 103 | ||
104 | #include <linux/serial.h> | 104 | #include <linux/serial.h> |
105 | #include <linux/generic_serial.h> | 105 | #include <linux/generic_serial.h> |
106 | #include <linux/tty_flip.h> | ||
106 | 107 | ||
107 | #include "ser_a2232.h" | 108 | #include "ser_a2232.h" |
108 | #include "ser_a2232fw.h" | 109 | #include "ser_a2232fw.h" |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index c2490e270f1f..a6b4f02bdceb 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -1095,17 +1095,17 @@ static inline void sx_receive_chars (struct sx_port *port) | |||
1095 | 1095 | ||
1096 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); | 1096 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); |
1097 | 1097 | ||
1098 | /* Don't copy past the end of the hardware receive buffer */ | ||
1099 | if (rx_op + c > 0x100) c = 0x100 - rx_op; | ||
1100 | |||
1101 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | ||
1102 | |||
1098 | /* Don't copy more bytes than there is room for in the buffer */ | 1103 | /* Don't copy more bytes than there is room for in the buffer */ |
1099 | 1104 | ||
1100 | c = tty_prepare_flip_string(tty, &rp, c); | 1105 | c = tty_prepare_flip_string(tty, &rp, c); |
1101 | 1106 | ||
1102 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | 1107 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); |
1103 | 1108 | ||
1104 | /* Don't copy past the end of the hardware receive buffer */ | ||
1105 | if (rx_op + c > 0x100) c = 0x100 - rx_op; | ||
1106 | |||
1107 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | ||
1108 | |||
1109 | /* If for one reason or another, we can't copy more data, we're done! */ | 1109 | /* If for one reason or another, we can't copy more data, we're done! */ |
1110 | if (c == 0) break; | 1110 | if (c == 0) break; |
1111 | 1111 | ||
@@ -2173,15 +2173,17 @@ static int probe_si (struct sx_board *board) | |||
2173 | if ( IS_SI1_BOARD(board)) { | 2173 | if ( IS_SI1_BOARD(board)) { |
2174 | /* This should be an SI1 board, which has this | 2174 | /* This should be an SI1 board, which has this |
2175 | location writable... */ | 2175 | location writable... */ |
2176 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) | 2176 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) { |
2177 | func_exit (); | 2177 | func_exit (); |
2178 | return 0; | 2178 | return 0; |
2179 | } | ||
2179 | } else { | 2180 | } else { |
2180 | /* This should be an SI2 board, which has the bottom | 2181 | /* This should be an SI2 board, which has the bottom |
2181 | 3 bits non-writable... */ | 2182 | 3 bits non-writable... */ |
2182 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) | 2183 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) { |
2183 | func_exit (); | 2184 | func_exit (); |
2184 | return 0; | 2185 | return 0; |
2186 | } | ||
2185 | } | 2187 | } |
2186 | 2188 | ||
2187 | /* Now we're pretty much convinced that there is an SI board here, | 2189 | /* Now we're pretty much convinced that there is an SI board here, |
@@ -2192,15 +2194,17 @@ static int probe_si (struct sx_board *board) | |||
2192 | if ( IS_SI1_BOARD(board)) { | 2194 | if ( IS_SI1_BOARD(board)) { |
2193 | /* This should be an SI1 board, which has this | 2195 | /* This should be an SI1 board, which has this |
2194 | location writable... */ | 2196 | location writable... */ |
2195 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) | 2197 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) { |
2196 | func_exit(); | 2198 | func_exit(); |
2197 | return 0; | 2199 | return 0; |
2200 | } | ||
2198 | } else { | 2201 | } else { |
2199 | /* This should be an SI2 board, which has the bottom | 2202 | /* This should be an SI2 board, which has the bottom |
2200 | 3 bits non-writable... */ | 2203 | 3 bits non-writable... */ |
2201 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) | 2204 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) { |
2202 | func_exit (); | 2205 | func_exit (); |
2203 | return 0; | 2206 | return 0; |
2207 | } | ||
2204 | } | 2208 | } |
2205 | 2209 | ||
2206 | printheader (); | 2210 | printheader (); |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index a85a60a93deb..b046390cd256 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -306,7 +306,7 @@ struct slgt_info { | |||
306 | int tx_active; | 306 | int tx_active; |
307 | 307 | ||
308 | unsigned char signals; /* serial signal states */ | 308 | unsigned char signals; /* serial signal states */ |
309 | unsigned int init_error; /* initialization error */ | 309 | int init_error; /* initialization error */ |
310 | 310 | ||
311 | unsigned char *tx_buf; | 311 | unsigned char *tx_buf; |
312 | int tx_count; | 312 | int tx_count; |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 5765f672e853..d58f82318853 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -243,7 +243,7 @@ static struct sysrq_key_op sysrq_term_op = { | |||
243 | 243 | ||
244 | static void moom_callback(void *ignored) | 244 | static void moom_callback(void *ignored) |
245 | { | 245 | { |
246 | out_of_memory(GFP_KERNEL, 0); | 246 | out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL], GFP_KERNEL, 0); |
247 | } | 247 | } |
248 | 248 | ||
249 | static DECLARE_WORK(moom_work, moom_callback, NULL); | 249 | static DECLARE_WORK(moom_work, moom_callback, NULL); |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 41a94bc79f67..eb2eb3e12d6a 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -250,12 +250,17 @@ tipar_open(struct inode *inode, struct file *file) | |||
250 | { | 250 | { |
251 | unsigned int minor = iminor(inode) - TIPAR_MINOR; | 251 | unsigned int minor = iminor(inode) - TIPAR_MINOR; |
252 | 252 | ||
253 | if (minor > tp_count - 1) | 253 | if (tp_count == 0 || minor > tp_count - 1) |
254 | return -ENXIO; | 254 | return -ENXIO; |
255 | 255 | ||
256 | if (test_and_set_bit(minor, &opened)) | 256 | if (test_and_set_bit(minor, &opened)) |
257 | return -EBUSY; | 257 | return -EBUSY; |
258 | 258 | ||
259 | if (!table[minor].dev) { | ||
260 | printk(KERN_ERR "%s: NULL device for minor %u\n", | ||
261 | __FUNCTION__, minor); | ||
262 | return -ENXIO; | ||
263 | } | ||
259 | parport_claim_or_block(table[minor].dev); | 264 | parport_claim_or_block(table[minor].dev); |
260 | init_ti_parallel(minor); | 265 | init_ti_parallel(minor); |
261 | parport_release(table[minor].dev); | 266 | parport_release(table[minor].dev); |
@@ -510,16 +515,20 @@ tipar_init_module(void) | |||
510 | err = PTR_ERR(tipar_class); | 515 | err = PTR_ERR(tipar_class); |
511 | goto out_chrdev; | 516 | goto out_chrdev; |
512 | } | 517 | } |
513 | if (parport_register_driver(&tipar_driver)) { | 518 | if (parport_register_driver(&tipar_driver) || tp_count == 0) { |
514 | printk(KERN_ERR "tipar: unable to register with parport\n"); | 519 | printk(KERN_ERR "tipar: unable to register with parport\n"); |
515 | err = -EIO; | 520 | err = -EIO; |
516 | goto out; | 521 | goto out_class; |
517 | } | 522 | } |
518 | 523 | ||
519 | err = 0; | 524 | err = 0; |
520 | goto out; | 525 | goto out; |
521 | 526 | ||
527 | out_class: | ||
528 | class_destroy(tipar_class); | ||
529 | |||
522 | out_chrdev: | 530 | out_chrdev: |
531 | devfs_remove("ticables/par"); | ||
523 | unregister_chrdev(TIPAR_MAJOR, "tipar"); | 532 | unregister_chrdev(TIPAR_MAJOR, "tipar"); |
524 | out: | 533 | out: |
525 | return err; | 534 | return err; |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index ec7590951af5..24095f6ee6da 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -33,6 +33,7 @@ | |||
33 | static int TPM_INF_DATA; | 33 | static int TPM_INF_DATA; |
34 | static int TPM_INF_ADDR; | 34 | static int TPM_INF_ADDR; |
35 | static int TPM_INF_BASE; | 35 | static int TPM_INF_BASE; |
36 | static int TPM_INF_ADDR_LEN; | ||
36 | static int TPM_INF_PORT_LEN; | 37 | static int TPM_INF_PORT_LEN; |
37 | 38 | ||
38 | /* TPM header definitions */ | 39 | /* TPM header definitions */ |
@@ -195,6 +196,7 @@ static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
195 | int i; | 196 | int i; |
196 | int ret; | 197 | int ret; |
197 | u32 size = 0; | 198 | u32 size = 0; |
199 | number_of_wtx = 0; | ||
198 | 200 | ||
199 | recv_begin: | 201 | recv_begin: |
200 | /* start receiving header */ | 202 | /* start receiving header */ |
@@ -378,24 +380,35 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
378 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | 380 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
379 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { | 381 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { |
380 | TPM_INF_ADDR = pnp_port_start(dev, 0); | 382 | TPM_INF_ADDR = pnp_port_start(dev, 0); |
383 | TPM_INF_ADDR_LEN = pnp_port_len(dev, 0); | ||
381 | TPM_INF_DATA = (TPM_INF_ADDR + 1); | 384 | TPM_INF_DATA = (TPM_INF_ADDR + 1); |
382 | TPM_INF_BASE = pnp_port_start(dev, 1); | 385 | TPM_INF_BASE = pnp_port_start(dev, 1); |
383 | TPM_INF_PORT_LEN = pnp_port_len(dev, 1); | 386 | TPM_INF_PORT_LEN = pnp_port_len(dev, 1); |
384 | if (!TPM_INF_PORT_LEN) | 387 | if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) { |
385 | return -EINVAL; | 388 | rc = -EINVAL; |
389 | goto err_last; | ||
390 | } | ||
386 | dev_info(&dev->dev, "Found %s with ID %s\n", | 391 | dev_info(&dev->dev, "Found %s with ID %s\n", |
387 | dev->name, dev_id->id); | 392 | dev->name, dev_id->id); |
388 | if (!((TPM_INF_BASE >> 8) & 0xff)) | 393 | if (!((TPM_INF_BASE >> 8) & 0xff)) { |
389 | return -EINVAL; | 394 | rc = -EINVAL; |
395 | goto err_last; | ||
396 | } | ||
390 | /* publish my base address and request region */ | 397 | /* publish my base address and request region */ |
391 | tpm_inf.base = TPM_INF_BASE; | 398 | tpm_inf.base = TPM_INF_BASE; |
392 | if (request_region | 399 | if (request_region |
393 | (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { | 400 | (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { |
394 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | 401 | rc = -EINVAL; |
395 | return -EINVAL; | 402 | goto err_last; |
403 | } | ||
404 | if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN, | ||
405 | "tpm_infineon0") == NULL) { | ||
406 | rc = -EINVAL; | ||
407 | goto err_last; | ||
396 | } | 408 | } |
397 | } else { | 409 | } else { |
398 | return -EINVAL; | 410 | rc = -EINVAL; |
411 | goto err_last; | ||
399 | } | 412 | } |
400 | 413 | ||
401 | /* query chip for its vendor, its version number a.s.o. */ | 414 | /* query chip for its vendor, its version number a.s.o. */ |
@@ -443,8 +456,8 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
443 | dev_err(&dev->dev, | 456 | dev_err(&dev->dev, |
444 | "Could not set IO-ports to 0x%lx\n", | 457 | "Could not set IO-ports to 0x%lx\n", |
445 | tpm_inf.base); | 458 | tpm_inf.base); |
446 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | 459 | rc = -EIO; |
447 | return -EIO; | 460 | goto err_release_region; |
448 | } | 461 | } |
449 | 462 | ||
450 | /* activate register */ | 463 | /* activate register */ |
@@ -471,14 +484,21 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
471 | 484 | ||
472 | rc = tpm_register_hardware(&dev->dev, &tpm_inf); | 485 | rc = tpm_register_hardware(&dev->dev, &tpm_inf); |
473 | if (rc < 0) { | 486 | if (rc < 0) { |
474 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | 487 | rc = -ENODEV; |
475 | return -ENODEV; | 488 | goto err_release_region; |
476 | } | 489 | } |
477 | return 0; | 490 | return 0; |
478 | } else { | 491 | } else { |
479 | dev_info(&dev->dev, "No Infineon TPM found!\n"); | 492 | rc = -ENODEV; |
480 | return -ENODEV; | 493 | goto err_release_region; |
481 | } | 494 | } |
495 | |||
496 | err_release_region: | ||
497 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | ||
498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | ||
499 | |||
500 | err_last: | ||
501 | return rc; | ||
482 | } | 502 | } |
483 | 503 | ||
484 | static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | 504 | static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) |
@@ -518,5 +538,5 @@ module_exit(cleanup_inf); | |||
518 | 538 | ||
519 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 539 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
520 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 540 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
521 | MODULE_VERSION("1.6"); | 541 | MODULE_VERSION("1.7"); |
522 | MODULE_LICENSE("GPL"); | 542 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 076e07c1da38..53d3d066554e 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -268,6 +268,8 @@ static struct tty_buffer *tty_buffer_alloc(size_t size) | |||
268 | p->size = size; | 268 | p->size = size; |
269 | p->next = NULL; | 269 | p->next = NULL; |
270 | p->active = 0; | 270 | p->active = 0; |
271 | p->commit = 0; | ||
272 | p->read = 0; | ||
271 | p->char_buf_ptr = (char *)(p->data); | 273 | p->char_buf_ptr = (char *)(p->data); |
272 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | 274 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; |
273 | /* printk("Flip create %p\n", p); */ | 275 | /* printk("Flip create %p\n", p); */ |
@@ -298,8 +300,10 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | |||
298 | *tbh = t->next; | 300 | *tbh = t->next; |
299 | t->next = NULL; | 301 | t->next = NULL; |
300 | t->used = 0; | 302 | t->used = 0; |
303 | t->commit = 0; | ||
304 | t->read = 0; | ||
301 | /* DEBUG ONLY */ | 305 | /* DEBUG ONLY */ |
302 | memset(t->data, '*', size); | 306 | /* memset(t->data, '*', size); */ |
303 | /* printk("Flip recycle %p\n", t); */ | 307 | /* printk("Flip recycle %p\n", t); */ |
304 | return t; | 308 | return t; |
305 | } | 309 | } |
@@ -335,6 +339,7 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) | |||
335 | if (b != NULL) { | 339 | if (b != NULL) { |
336 | b->next = n; | 340 | b->next = n; |
337 | b->active = 0; | 341 | b->active = 0; |
342 | b->commit = b->used; | ||
338 | } else | 343 | } else |
339 | tty->buf.head = n; | 344 | tty->buf.head = n; |
340 | tty->buf.tail = n; | 345 | tty->buf.tail = n; |
@@ -1836,7 +1841,6 @@ static void release_dev(struct file * filp) | |||
1836 | tty_closing = tty->count <= 1; | 1841 | tty_closing = tty->count <= 1; |
1837 | o_tty_closing = o_tty && | 1842 | o_tty_closing = o_tty && |
1838 | (o_tty->count <= (pty_master ? 1 : 0)); | 1843 | (o_tty->count <= (pty_master ? 1 : 0)); |
1839 | up(&tty_sem); | ||
1840 | do_sleep = 0; | 1844 | do_sleep = 0; |
1841 | 1845 | ||
1842 | if (tty_closing) { | 1846 | if (tty_closing) { |
@@ -1864,6 +1868,7 @@ static void release_dev(struct file * filp) | |||
1864 | 1868 | ||
1865 | printk(KERN_WARNING "release_dev: %s: read/write wait queue " | 1869 | printk(KERN_WARNING "release_dev: %s: read/write wait queue " |
1866 | "active!\n", tty_name(tty, buf)); | 1870 | "active!\n", tty_name(tty, buf)); |
1871 | up(&tty_sem); | ||
1867 | schedule(); | 1872 | schedule(); |
1868 | } | 1873 | } |
1869 | 1874 | ||
@@ -1872,8 +1877,6 @@ static void release_dev(struct file * filp) | |||
1872 | * both sides, and we've completed the last operation that could | 1877 | * both sides, and we've completed the last operation that could |
1873 | * block, so it's safe to proceed with closing. | 1878 | * block, so it's safe to proceed with closing. |
1874 | */ | 1879 | */ |
1875 | |||
1876 | down(&tty_sem); | ||
1877 | if (pty_master) { | 1880 | if (pty_master) { |
1878 | if (--o_tty->count < 0) { | 1881 | if (--o_tty->count < 0) { |
1879 | printk(KERN_WARNING "release_dev: bad pty slave count " | 1882 | printk(KERN_WARNING "release_dev: bad pty slave count " |
@@ -1887,7 +1890,6 @@ static void release_dev(struct file * filp) | |||
1887 | tty->count, tty_name(tty, buf)); | 1890 | tty->count, tty_name(tty, buf)); |
1888 | tty->count = 0; | 1891 | tty->count = 0; |
1889 | } | 1892 | } |
1890 | up(&tty_sem); | ||
1891 | 1893 | ||
1892 | /* | 1894 | /* |
1893 | * We've decremented tty->count, so we need to remove this file | 1895 | * We've decremented tty->count, so we need to remove this file |
@@ -1932,6 +1934,8 @@ static void release_dev(struct file * filp) | |||
1932 | read_unlock(&tasklist_lock); | 1934 | read_unlock(&tasklist_lock); |
1933 | } | 1935 | } |
1934 | 1936 | ||
1937 | up(&tty_sem); | ||
1938 | |||
1935 | /* check whether both sides are closing ... */ | 1939 | /* check whether both sides are closing ... */ |
1936 | if (!tty_closing || (o_tty && !o_tty_closing)) | 1940 | if (!tty_closing || (o_tty && !o_tty_closing)) |
1937 | return; | 1941 | return; |
@@ -2752,6 +2756,9 @@ static void flush_to_ldisc(void *private_) | |||
2752 | unsigned long flags; | 2756 | unsigned long flags; |
2753 | struct tty_ldisc *disc; | 2757 | struct tty_ldisc *disc; |
2754 | struct tty_buffer *tbuf; | 2758 | struct tty_buffer *tbuf; |
2759 | int count; | ||
2760 | char *char_buf; | ||
2761 | unsigned char *flag_buf; | ||
2755 | 2762 | ||
2756 | disc = tty_ldisc_ref(tty); | 2763 | disc = tty_ldisc_ref(tty); |
2757 | if (disc == NULL) /* !TTY_LDISC */ | 2764 | if (disc == NULL) /* !TTY_LDISC */ |
@@ -2765,16 +2772,20 @@ static void flush_to_ldisc(void *private_) | |||
2765 | goto out; | 2772 | goto out; |
2766 | } | 2773 | } |
2767 | spin_lock_irqsave(&tty->buf.lock, flags); | 2774 | spin_lock_irqsave(&tty->buf.lock, flags); |
2768 | while((tbuf = tty->buf.head) != NULL && !tbuf->active) { | 2775 | while((tbuf = tty->buf.head) != NULL) { |
2776 | while ((count = tbuf->commit - tbuf->read) != 0) { | ||
2777 | char_buf = tbuf->char_buf_ptr + tbuf->read; | ||
2778 | flag_buf = tbuf->flag_buf_ptr + tbuf->read; | ||
2779 | tbuf->read += count; | ||
2780 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
2781 | disc->receive_buf(tty, char_buf, flag_buf, count); | ||
2782 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
2783 | } | ||
2784 | if (tbuf->active) | ||
2785 | break; | ||
2769 | tty->buf.head = tbuf->next; | 2786 | tty->buf.head = tbuf->next; |
2770 | if (tty->buf.head == NULL) | 2787 | if (tty->buf.head == NULL) |
2771 | tty->buf.tail = NULL; | 2788 | tty->buf.tail = NULL; |
2772 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
2773 | /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */ | ||
2774 | disc->receive_buf(tty, tbuf->char_buf_ptr, | ||
2775 | tbuf->flag_buf_ptr, | ||
2776 | tbuf->used); | ||
2777 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
2778 | tty_buffer_free(tty, tbuf); | 2789 | tty_buffer_free(tty, tbuf); |
2779 | } | 2790 | } |
2780 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 2791 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
@@ -2871,8 +2882,10 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
2871 | { | 2882 | { |
2872 | unsigned long flags; | 2883 | unsigned long flags; |
2873 | spin_lock_irqsave(&tty->buf.lock, flags); | 2884 | spin_lock_irqsave(&tty->buf.lock, flags); |
2874 | if (tty->buf.tail != NULL) | 2885 | if (tty->buf.tail != NULL) { |
2875 | tty->buf.tail->active = 0; | 2886 | tty->buf.tail->active = 0; |
2887 | tty->buf.tail->commit = tty->buf.tail->used; | ||
2888 | } | ||
2876 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 2889 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
2877 | 2890 | ||
2878 | if (tty->low_latency) | 2891 | if (tty->low_latency) |
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c index 37c9e13ad3ac..8d6b249ad66b 100644 --- a/drivers/char/watchdog/pcwd.c +++ b/drivers/char/watchdog/pcwd.c | |||
@@ -49,29 +49,37 @@ | |||
49 | * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ | 49 | * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ |
50 | */ | 50 | */ |
51 | 51 | ||
52 | #include <linux/module.h> | 52 | #include <linux/config.h> /* For CONFIG_WATCHDOG_NOWAYOUT/... */ |
53 | #include <linux/moduleparam.h> | 53 | #include <linux/module.h> /* For module specific items */ |
54 | #include <linux/types.h> | 54 | #include <linux/moduleparam.h> /* For new moduleparam's */ |
55 | #include <linux/timer.h> | 55 | #include <linux/types.h> /* For standard types (like size_t) */ |
56 | #include <linux/jiffies.h> | 56 | #include <linux/errno.h> /* For the -ENODEV/... values */ |
57 | #include <linux/config.h> | 57 | #include <linux/kernel.h> /* For printk/panic/... */ |
58 | #include <linux/wait.h> | 58 | #include <linux/delay.h> /* For mdelay function */ |
59 | #include <linux/slab.h> | 59 | #include <linux/timer.h> /* For timer related operations */ |
60 | #include <linux/ioport.h> | 60 | #include <linux/jiffies.h> /* For jiffies stuff */ |
61 | #include <linux/delay.h> | 61 | #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */ |
62 | #include <linux/fs.h> | 62 | #include <linux/watchdog.h> /* For the watchdog specific items */ |
63 | #include <linux/miscdevice.h> | 63 | #include <linux/notifier.h> /* For notifier support */ |
64 | #include <linux/watchdog.h> | 64 | #include <linux/reboot.h> /* For reboot_notifier stuff */ |
65 | #include <linux/notifier.h> | 65 | #include <linux/init.h> /* For __init/__exit/... */ |
66 | #include <linux/init.h> | 66 | #include <linux/fs.h> /* For file operations */ |
67 | #include <linux/spinlock.h> | 67 | #include <linux/ioport.h> /* For io-port access */ |
68 | #include <linux/reboot.h> | 68 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
69 | #include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */ | 69 | #include <linux/sched.h> /* TASK_INTERRUPTIBLE, set_current_state() and friends */ |
70 | #include <asm/uaccess.h> | 70 | #include <linux/slab.h> /* For kmalloc */ |
71 | #include <asm/io.h> | ||
72 | 71 | ||
73 | #define WD_VER "1.16 (06/12/2004)" | 72 | #include <asm/uaccess.h> /* For copy_to_user/put_user/... */ |
74 | #define PFX "pcwd: " | 73 | #include <asm/io.h> /* For inb/outb/... */ |
74 | |||
75 | /* Module and version information */ | ||
76 | #define WATCHDOG_VERSION "1.16" | ||
77 | #define WATCHDOG_DATE "03 Jan 2006" | ||
78 | #define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog" | ||
79 | #define WATCHDOG_NAME "pcwd" | ||
80 | #define PFX WATCHDOG_NAME ": " | ||
81 | #define DRIVER_VERSION WATCHDOG_DRIVER_NAME " driver, v" WATCHDOG_VERSION " (" WATCHDOG_DATE ")\n" | ||
82 | #define WD_VER WATCHDOG_VERSION " (" WATCHDOG_DATE ")" | ||
75 | 83 | ||
76 | /* | 84 | /* |
77 | * It should be noted that PCWD_REVISION_B was removed because A and B | 85 | * It should be noted that PCWD_REVISION_B was removed because A and B |
@@ -85,36 +93,38 @@ | |||
85 | 93 | ||
86 | /* | 94 | /* |
87 | * These are the defines that describe the control status bits for the | 95 | * These are the defines that describe the control status bits for the |
88 | * PC Watchdog card, revision A. | 96 | * PCI-PC Watchdog card. |
89 | */ | 97 | */ |
98 | /* Port 1 : Control Status #1 for the PC Watchdog card, revision A. */ | ||
90 | #define WD_WDRST 0x01 /* Previously reset state */ | 99 | #define WD_WDRST 0x01 /* Previously reset state */ |
91 | #define WD_T110 0x02 /* Temperature overheat sense */ | 100 | #define WD_T110 0x02 /* Temperature overheat sense */ |
92 | #define WD_HRTBT 0x04 /* Heartbeat sense */ | 101 | #define WD_HRTBT 0x04 /* Heartbeat sense */ |
93 | #define WD_RLY2 0x08 /* External relay triggered */ | 102 | #define WD_RLY2 0x08 /* External relay triggered */ |
94 | #define WD_SRLY2 0x80 /* Software external relay triggered */ | 103 | #define WD_SRLY2 0x80 /* Software external relay triggered */ |
95 | 104 | /* Port 1 : Control Status #1 for the PC Watchdog card, revision C. */ | |
96 | /* | ||
97 | * These are the defines that describe the control status bits for the | ||
98 | * PC Watchdog card, revision C. | ||
99 | */ | ||
100 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ | 105 | #define WD_REVC_WTRP 0x01 /* Watchdog Trip status */ |
101 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ | 106 | #define WD_REVC_HRBT 0x02 /* Watchdog Heartbeat */ |
102 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ | 107 | #define WD_REVC_TTRP 0x04 /* Temperature Trip status */ |
108 | /* Port 2 : Control Status #2 */ | ||
109 | #define WD_WDIS 0x10 /* Watchdog Disabled */ | ||
110 | #define WD_ENTP 0x20 /* Watchdog Enable Temperature Trip */ | ||
111 | #define WD_SSEL 0x40 /* Watchdog Switch Select (1:SW1 <-> 0:SW2) */ | ||
112 | #define WD_WCMD 0x80 /* Watchdog Command Mode */ | ||
103 | 113 | ||
104 | /* max. time we give an ISA watchdog card to process a command */ | 114 | /* max. time we give an ISA watchdog card to process a command */ |
105 | /* 500ms for each 4 bit response (according to spec.) */ | 115 | /* 500ms for each 4 bit response (according to spec.) */ |
106 | #define ISA_COMMAND_TIMEOUT 1000 | 116 | #define ISA_COMMAND_TIMEOUT 1000 |
107 | 117 | ||
108 | /* Watchdog's internal commands */ | 118 | /* Watchdog's internal commands */ |
109 | #define CMD_ISA_IDLE 0x00 | 119 | #define CMD_ISA_IDLE 0x00 |
110 | #define CMD_ISA_VERSION_INTEGER 0x01 | 120 | #define CMD_ISA_VERSION_INTEGER 0x01 |
111 | #define CMD_ISA_VERSION_TENTH 0x02 | 121 | #define CMD_ISA_VERSION_TENTH 0x02 |
112 | #define CMD_ISA_VERSION_HUNDRETH 0x03 | 122 | #define CMD_ISA_VERSION_HUNDRETH 0x03 |
113 | #define CMD_ISA_VERSION_MINOR 0x04 | 123 | #define CMD_ISA_VERSION_MINOR 0x04 |
114 | #define CMD_ISA_SWITCH_SETTINGS 0x05 | 124 | #define CMD_ISA_SWITCH_SETTINGS 0x05 |
115 | #define CMD_ISA_DELAY_TIME_2SECS 0x0A | 125 | #define CMD_ISA_DELAY_TIME_2SECS 0x0A |
116 | #define CMD_ISA_DELAY_TIME_4SECS 0x0B | 126 | #define CMD_ISA_DELAY_TIME_4SECS 0x0B |
117 | #define CMD_ISA_DELAY_TIME_8SECS 0x0C | 127 | #define CMD_ISA_DELAY_TIME_8SECS 0x0C |
118 | 128 | ||
119 | /* | 129 | /* |
120 | * We are using an kernel timer to do the pinging of the watchdog | 130 | * We are using an kernel timer to do the pinging of the watchdog |
@@ -130,15 +140,17 @@ static int cards_found; | |||
130 | /* internal variables */ | 140 | /* internal variables */ |
131 | static atomic_t open_allowed = ATOMIC_INIT(1); | 141 | static atomic_t open_allowed = ATOMIC_INIT(1); |
132 | static char expect_close; | 142 | static char expect_close; |
133 | static struct timer_list timer; | ||
134 | static unsigned long next_heartbeat; | ||
135 | static int temp_panic; | 143 | static int temp_panic; |
136 | static int revision; /* The card's revision */ | 144 | static struct { /* this is private data for each ISA-PC watchdog card */ |
137 | static int supports_temp; /* Wether or not the card has a temperature device */ | 145 | int revision; /* The card's revision */ |
138 | static int command_mode; /* Wether or not the card is in command mode */ | 146 | int supports_temp; /* Wether or not the card has a temperature device */ |
139 | static int initial_status; /* The card's boot status */ | 147 | int command_mode; /* Wether or not the card is in command mode */ |
140 | static int current_readport; /* The cards I/O address */ | 148 | int boot_status; /* The card's boot status */ |
141 | static spinlock_t io_lock; | 149 | int io_addr; /* The cards I/O address */ |
150 | spinlock_t io_lock; /* the lock for io operations */ | ||
151 | struct timer_list timer; /* The timer that pings the watchdog */ | ||
152 | unsigned long next_heartbeat; /* the next_heartbeat for the timer */ | ||
153 | } pcwd_private; | ||
142 | 154 | ||
143 | /* module parameters */ | 155 | /* module parameters */ |
144 | #define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ | 156 | #define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat */ |
@@ -161,14 +173,14 @@ static int send_isa_command(int cmd) | |||
161 | int port0, last_port0; /* Double read for stabilising */ | 173 | int port0, last_port0; /* Double read for stabilising */ |
162 | 174 | ||
163 | /* The WCMD bit must be 1 and the command is only 4 bits in size */ | 175 | /* The WCMD bit must be 1 and the command is only 4 bits in size */ |
164 | control_status = (cmd & 0x0F) | 0x80; | 176 | control_status = (cmd & 0x0F) | WD_WCMD; |
165 | outb_p(control_status, current_readport + 2); | 177 | outb_p(control_status, pcwd_private.io_addr + 2); |
166 | udelay(ISA_COMMAND_TIMEOUT); | 178 | udelay(ISA_COMMAND_TIMEOUT); |
167 | 179 | ||
168 | port0 = inb_p(current_readport); | 180 | port0 = inb_p(pcwd_private.io_addr); |
169 | for (i = 0; i < 25; ++i) { | 181 | for (i = 0; i < 25; ++i) { |
170 | last_port0 = port0; | 182 | last_port0 = port0; |
171 | port0 = inb_p(current_readport); | 183 | port0 = inb_p(pcwd_private.io_addr); |
172 | 184 | ||
173 | if (port0 == last_port0) | 185 | if (port0 == last_port0) |
174 | break; /* Data is stable */ | 186 | break; /* Data is stable */ |
@@ -184,7 +196,7 @@ static int set_command_mode(void) | |||
184 | int i, found=0, count=0; | 196 | int i, found=0, count=0; |
185 | 197 | ||
186 | /* Set the card into command mode */ | 198 | /* Set the card into command mode */ |
187 | spin_lock(&io_lock); | 199 | spin_lock(&pcwd_private.io_lock); |
188 | while ((!found) && (count < 3)) { | 200 | while ((!found) && (count < 3)) { |
189 | i = send_isa_command(CMD_ISA_IDLE); | 201 | i = send_isa_command(CMD_ISA_IDLE); |
190 | 202 | ||
@@ -192,15 +204,15 @@ static int set_command_mode(void) | |||
192 | found = 1; | 204 | found = 1; |
193 | else if (i == 0xF3) { | 205 | else if (i == 0xF3) { |
194 | /* Card does not like what we've done to it */ | 206 | /* Card does not like what we've done to it */ |
195 | outb_p(0x00, current_readport + 2); | 207 | outb_p(0x00, pcwd_private.io_addr + 2); |
196 | udelay(1200); /* Spec says wait 1ms */ | 208 | udelay(1200); /* Spec says wait 1ms */ |
197 | outb_p(0x00, current_readport + 2); | 209 | outb_p(0x00, pcwd_private.io_addr + 2); |
198 | udelay(ISA_COMMAND_TIMEOUT); | 210 | udelay(ISA_COMMAND_TIMEOUT); |
199 | } | 211 | } |
200 | count++; | 212 | count++; |
201 | } | 213 | } |
202 | spin_unlock(&io_lock); | 214 | spin_unlock(&pcwd_private.io_lock); |
203 | command_mode = found; | 215 | pcwd_private.command_mode = found; |
204 | 216 | ||
205 | return(found); | 217 | return(found); |
206 | } | 218 | } |
@@ -208,12 +220,95 @@ static int set_command_mode(void) | |||
208 | static void unset_command_mode(void) | 220 | static void unset_command_mode(void) |
209 | { | 221 | { |
210 | /* Set the card into normal mode */ | 222 | /* Set the card into normal mode */ |
211 | spin_lock(&io_lock); | 223 | spin_lock(&pcwd_private.io_lock); |
212 | outb_p(0x00, current_readport + 2); | 224 | outb_p(0x00, pcwd_private.io_addr + 2); |
213 | udelay(ISA_COMMAND_TIMEOUT); | 225 | udelay(ISA_COMMAND_TIMEOUT); |
214 | spin_unlock(&io_lock); | 226 | spin_unlock(&pcwd_private.io_lock); |
227 | |||
228 | pcwd_private.command_mode = 0; | ||
229 | } | ||
230 | |||
231 | static inline void pcwd_check_temperature_support(void) | ||
232 | { | ||
233 | if (inb(pcwd_private.io_addr) != 0xF0) | ||
234 | pcwd_private.supports_temp = 1; | ||
235 | } | ||
236 | |||
237 | static inline char *get_firmware(void) | ||
238 | { | ||
239 | int one, ten, hund, minor; | ||
240 | char *ret; | ||
241 | |||
242 | ret = kmalloc(6, GFP_KERNEL); | ||
243 | if(ret == NULL) | ||
244 | return NULL; | ||
245 | |||
246 | if (set_command_mode()) { | ||
247 | one = send_isa_command(CMD_ISA_VERSION_INTEGER); | ||
248 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); | ||
249 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); | ||
250 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); | ||
251 | sprintf(ret, "%c.%c%c%c", one, ten, hund, minor); | ||
252 | } | ||
253 | else | ||
254 | sprintf(ret, "ERROR"); | ||
255 | |||
256 | unset_command_mode(); | ||
257 | return(ret); | ||
258 | } | ||
259 | |||
260 | static inline int pcwd_get_option_switches(void) | ||
261 | { | ||
262 | int option_switches=0; | ||
263 | |||
264 | if (set_command_mode()) { | ||
265 | /* Get switch settings */ | ||
266 | option_switches = send_isa_command(CMD_ISA_SWITCH_SETTINGS); | ||
267 | } | ||
268 | |||
269 | unset_command_mode(); | ||
270 | return(option_switches); | ||
271 | } | ||
272 | |||
273 | static void pcwd_show_card_info(void) | ||
274 | { | ||
275 | char *firmware; | ||
276 | int option_switches; | ||
277 | |||
278 | /* Get some extra info from the hardware (in command/debug/diag mode) */ | ||
279 | if (pcwd_private.revision == PCWD_REVISION_A) | ||
280 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", pcwd_private.io_addr); | ||
281 | else if (pcwd_private.revision == PCWD_REVISION_C) { | ||
282 | firmware = get_firmware(); | ||
283 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", | ||
284 | pcwd_private.io_addr, firmware); | ||
285 | kfree(firmware); | ||
286 | option_switches = pcwd_get_option_switches(); | ||
287 | printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", | ||
288 | option_switches, | ||
289 | ((option_switches & 0x10) ? "ON" : "OFF"), | ||
290 | ((option_switches & 0x08) ? "ON" : "OFF")); | ||
291 | |||
292 | /* Reprogram internal heartbeat to 2 seconds */ | ||
293 | if (set_command_mode()) { | ||
294 | send_isa_command(CMD_ISA_DELAY_TIME_2SECS); | ||
295 | unset_command_mode(); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | if (pcwd_private.supports_temp) | ||
300 | printk(KERN_INFO PFX "Temperature Option Detected\n"); | ||
301 | |||
302 | if (pcwd_private.boot_status & WDIOF_CARDRESET) | ||
303 | printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); | ||
304 | |||
305 | if (pcwd_private.boot_status & WDIOF_OVERHEAT) { | ||
306 | printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); | ||
307 | printk(KERN_EMERG PFX "CPU Overheat\n"); | ||
308 | } | ||
215 | 309 | ||
216 | command_mode = 0; | 310 | if (pcwd_private.boot_status == 0) |
311 | printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); | ||
217 | } | 312 | } |
218 | 313 | ||
219 | static void pcwd_timer_ping(unsigned long data) | 314 | static void pcwd_timer_ping(unsigned long data) |
@@ -222,25 +317,25 @@ static void pcwd_timer_ping(unsigned long data) | |||
222 | 317 | ||
223 | /* If we got a heartbeat pulse within the WDT_INTERVAL | 318 | /* If we got a heartbeat pulse within the WDT_INTERVAL |
224 | * we agree to ping the WDT */ | 319 | * we agree to ping the WDT */ |
225 | if(time_before(jiffies, next_heartbeat)) { | 320 | if(time_before(jiffies, pcwd_private.next_heartbeat)) { |
226 | /* Ping the watchdog */ | 321 | /* Ping the watchdog */ |
227 | spin_lock(&io_lock); | 322 | spin_lock(&pcwd_private.io_lock); |
228 | if (revision == PCWD_REVISION_A) { | 323 | if (pcwd_private.revision == PCWD_REVISION_A) { |
229 | /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ | 324 | /* Rev A cards are reset by setting the WD_WDRST bit in register 1 */ |
230 | wdrst_stat = inb_p(current_readport); | 325 | wdrst_stat = inb_p(pcwd_private.io_addr); |
231 | wdrst_stat &= 0x0F; | 326 | wdrst_stat &= 0x0F; |
232 | wdrst_stat |= WD_WDRST; | 327 | wdrst_stat |= WD_WDRST; |
233 | 328 | ||
234 | outb_p(wdrst_stat, current_readport + 1); | 329 | outb_p(wdrst_stat, pcwd_private.io_addr + 1); |
235 | } else { | 330 | } else { |
236 | /* Re-trigger watchdog by writing to port 0 */ | 331 | /* Re-trigger watchdog by writing to port 0 */ |
237 | outb_p(0x00, current_readport); | 332 | outb_p(0x00, pcwd_private.io_addr); |
238 | } | 333 | } |
239 | 334 | ||
240 | /* Re-set the timer interval */ | 335 | /* Re-set the timer interval */ |
241 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 336 | mod_timer(&pcwd_private.timer, jiffies + WDT_INTERVAL); |
242 | 337 | ||
243 | spin_unlock(&io_lock); | 338 | spin_unlock(&pcwd_private.io_lock); |
244 | } else { | 339 | } else { |
245 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); | 340 | printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n"); |
246 | } | 341 | } |
@@ -250,19 +345,19 @@ static int pcwd_start(void) | |||
250 | { | 345 | { |
251 | int stat_reg; | 346 | int stat_reg; |
252 | 347 | ||
253 | next_heartbeat = jiffies + (heartbeat * HZ); | 348 | pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); |
254 | 349 | ||
255 | /* Start the timer */ | 350 | /* Start the timer */ |
256 | mod_timer(&timer, jiffies + WDT_INTERVAL); | 351 | mod_timer(&pcwd_private.timer, jiffies + WDT_INTERVAL); |
257 | 352 | ||
258 | /* Enable the port */ | 353 | /* Enable the port */ |
259 | if (revision == PCWD_REVISION_C) { | 354 | if (pcwd_private.revision == PCWD_REVISION_C) { |
260 | spin_lock(&io_lock); | 355 | spin_lock(&pcwd_private.io_lock); |
261 | outb_p(0x00, current_readport + 3); | 356 | outb_p(0x00, pcwd_private.io_addr + 3); |
262 | udelay(ISA_COMMAND_TIMEOUT); | 357 | udelay(ISA_COMMAND_TIMEOUT); |
263 | stat_reg = inb_p(current_readport + 2); | 358 | stat_reg = inb_p(pcwd_private.io_addr + 2); |
264 | spin_unlock(&io_lock); | 359 | spin_unlock(&pcwd_private.io_lock); |
265 | if (stat_reg & 0x10) { | 360 | if (stat_reg & WD_WDIS) { |
266 | printk(KERN_INFO PFX "Could not start watchdog\n"); | 361 | printk(KERN_INFO PFX "Could not start watchdog\n"); |
267 | return -EIO; | 362 | return -EIO; |
268 | } | 363 | } |
@@ -275,18 +370,18 @@ static int pcwd_stop(void) | |||
275 | int stat_reg; | 370 | int stat_reg; |
276 | 371 | ||
277 | /* Stop the timer */ | 372 | /* Stop the timer */ |
278 | del_timer(&timer); | 373 | del_timer(&pcwd_private.timer); |
279 | 374 | ||
280 | /* Disable the board */ | 375 | /* Disable the board */ |
281 | if (revision == PCWD_REVISION_C) { | 376 | if (pcwd_private.revision == PCWD_REVISION_C) { |
282 | spin_lock(&io_lock); | 377 | spin_lock(&pcwd_private.io_lock); |
283 | outb_p(0xA5, current_readport + 3); | 378 | outb_p(0xA5, pcwd_private.io_addr + 3); |
284 | udelay(ISA_COMMAND_TIMEOUT); | 379 | udelay(ISA_COMMAND_TIMEOUT); |
285 | outb_p(0xA5, current_readport + 3); | 380 | outb_p(0xA5, pcwd_private.io_addr + 3); |
286 | udelay(ISA_COMMAND_TIMEOUT); | 381 | udelay(ISA_COMMAND_TIMEOUT); |
287 | stat_reg = inb_p(current_readport + 2); | 382 | stat_reg = inb_p(pcwd_private.io_addr + 2); |
288 | spin_unlock(&io_lock); | 383 | spin_unlock(&pcwd_private.io_lock); |
289 | if ((stat_reg & 0x10) == 0) { | 384 | if ((stat_reg & WD_WDIS) == 0) { |
290 | printk(KERN_INFO PFX "Could not stop watchdog\n"); | 385 | printk(KERN_INFO PFX "Could not stop watchdog\n"); |
291 | return -EIO; | 386 | return -EIO; |
292 | } | 387 | } |
@@ -297,7 +392,7 @@ static int pcwd_stop(void) | |||
297 | static int pcwd_keepalive(void) | 392 | static int pcwd_keepalive(void) |
298 | { | 393 | { |
299 | /* user land ping */ | 394 | /* user land ping */ |
300 | next_heartbeat = jiffies + (heartbeat * HZ); | 395 | pcwd_private.next_heartbeat = jiffies + (heartbeat * HZ); |
301 | return 0; | 396 | return 0; |
302 | } | 397 | } |
303 | 398 | ||
@@ -315,23 +410,23 @@ static int pcwd_get_status(int *status) | |||
315 | int card_status; | 410 | int card_status; |
316 | 411 | ||
317 | *status=0; | 412 | *status=0; |
318 | spin_lock(&io_lock); | 413 | spin_lock(&pcwd_private.io_lock); |
319 | if (revision == PCWD_REVISION_A) | 414 | if (pcwd_private.revision == PCWD_REVISION_A) |
320 | /* Rev A cards return status information from | 415 | /* Rev A cards return status information from |
321 | * the base register, which is used for the | 416 | * the base register, which is used for the |
322 | * temperature in other cards. */ | 417 | * temperature in other cards. */ |
323 | card_status = inb(current_readport); | 418 | card_status = inb(pcwd_private.io_addr); |
324 | else { | 419 | else { |
325 | /* Rev C cards return card status in the base | 420 | /* Rev C cards return card status in the base |
326 | * address + 1 register. And use different bits | 421 | * address + 1 register. And use different bits |
327 | * to indicate a card initiated reset, and an | 422 | * to indicate a card initiated reset, and an |
328 | * over-temperature condition. And the reboot | 423 | * over-temperature condition. And the reboot |
329 | * status can be reset. */ | 424 | * status can be reset. */ |
330 | card_status = inb(current_readport + 1); | 425 | card_status = inb(pcwd_private.io_addr + 1); |
331 | } | 426 | } |
332 | spin_unlock(&io_lock); | 427 | spin_unlock(&pcwd_private.io_lock); |
333 | 428 | ||
334 | if (revision == PCWD_REVISION_A) { | 429 | if (pcwd_private.revision == PCWD_REVISION_A) { |
335 | if (card_status & WD_WDRST) | 430 | if (card_status & WD_WDRST) |
336 | *status |= WDIOF_CARDRESET; | 431 | *status |= WDIOF_CARDRESET; |
337 | 432 | ||
@@ -360,10 +455,10 @@ static int pcwd_get_status(int *status) | |||
360 | 455 | ||
361 | static int pcwd_clear_status(void) | 456 | static int pcwd_clear_status(void) |
362 | { | 457 | { |
363 | if (revision == PCWD_REVISION_C) { | 458 | if (pcwd_private.revision == PCWD_REVISION_C) { |
364 | spin_lock(&io_lock); | 459 | spin_lock(&pcwd_private.io_lock); |
365 | outb_p(0x00, current_readport + 1); /* clear reset status */ | 460 | outb_p(0x00, pcwd_private.io_addr + 1); /* clear reset status */ |
366 | spin_unlock(&io_lock); | 461 | spin_unlock(&pcwd_private.io_lock); |
367 | } | 462 | } |
368 | return 0; | 463 | return 0; |
369 | } | 464 | } |
@@ -371,20 +466,20 @@ static int pcwd_clear_status(void) | |||
371 | static int pcwd_get_temperature(int *temperature) | 466 | static int pcwd_get_temperature(int *temperature) |
372 | { | 467 | { |
373 | /* check that port 0 gives temperature info and no command results */ | 468 | /* check that port 0 gives temperature info and no command results */ |
374 | if (command_mode) | 469 | if (pcwd_private.command_mode) |
375 | return -1; | 470 | return -1; |
376 | 471 | ||
377 | *temperature = 0; | 472 | *temperature = 0; |
378 | if (!supports_temp) | 473 | if (!pcwd_private.supports_temp) |
379 | return -ENODEV; | 474 | return -ENODEV; |
380 | 475 | ||
381 | /* | 476 | /* |
382 | * Convert celsius to fahrenheit, since this was | 477 | * Convert celsius to fahrenheit, since this was |
383 | * the decided 'standard' for this return value. | 478 | * the decided 'standard' for this return value. |
384 | */ | 479 | */ |
385 | spin_lock(&io_lock); | 480 | spin_lock(&pcwd_private.io_lock); |
386 | *temperature = ((inb(current_readport)) * 9 / 5) + 32; | 481 | *temperature = ((inb(pcwd_private.io_addr)) * 9 / 5) + 32; |
387 | spin_unlock(&io_lock); | 482 | spin_unlock(&pcwd_private.io_lock); |
388 | 483 | ||
389 | return 0; | 484 | return 0; |
390 | } | 485 | } |
@@ -425,7 +520,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
425 | return put_user(status, argp); | 520 | return put_user(status, argp); |
426 | 521 | ||
427 | case WDIOC_GETBOOTSTATUS: | 522 | case WDIOC_GETBOOTSTATUS: |
428 | return put_user(initial_status, argp); | 523 | return put_user(pcwd_private.boot_status, argp); |
429 | 524 | ||
430 | case WDIOC_GETTEMP: | 525 | case WDIOC_GETTEMP: |
431 | if (pcwd_get_temperature(&temperature)) | 526 | if (pcwd_get_temperature(&temperature)) |
@@ -434,7 +529,7 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, | |||
434 | return put_user(temperature, argp); | 529 | return put_user(temperature, argp); |
435 | 530 | ||
436 | case WDIOC_SETOPTIONS: | 531 | case WDIOC_SETOPTIONS: |
437 | if (revision == PCWD_REVISION_C) | 532 | if (pcwd_private.revision == PCWD_REVISION_C) |
438 | { | 533 | { |
439 | if(copy_from_user(&rv, argp, sizeof(int))) | 534 | if(copy_from_user(&rv, argp, sizeof(int))) |
440 | return -EFAULT; | 535 | return -EFAULT; |
@@ -550,7 +645,7 @@ static ssize_t pcwd_temp_read(struct file *file, char __user *buf, size_t count, | |||
550 | 645 | ||
551 | static int pcwd_temp_open(struct inode *inode, struct file *file) | 646 | static int pcwd_temp_open(struct inode *inode, struct file *file) |
552 | { | 647 | { |
553 | if (!supports_temp) | 648 | if (!pcwd_private.supports_temp) |
554 | return -ENODEV; | 649 | return -ENODEV; |
555 | 650 | ||
556 | return nonseekable_open(inode, file); | 651 | return nonseekable_open(inode, file); |
@@ -616,68 +711,24 @@ static struct notifier_block pcwd_notifier = { | |||
616 | * Init & exit routines | 711 | * Init & exit routines |
617 | */ | 712 | */ |
618 | 713 | ||
619 | static inline void get_support(void) | ||
620 | { | ||
621 | if (inb(current_readport) != 0xF0) | ||
622 | supports_temp = 1; | ||
623 | } | ||
624 | |||
625 | static inline int get_revision(void) | 714 | static inline int get_revision(void) |
626 | { | 715 | { |
627 | int r = PCWD_REVISION_C; | 716 | int r = PCWD_REVISION_C; |
628 | 717 | ||
629 | spin_lock(&io_lock); | 718 | spin_lock(&pcwd_private.io_lock); |
630 | /* REV A cards use only 2 io ports; test | 719 | /* REV A cards use only 2 io ports; test |
631 | * presumes a floating bus reads as 0xff. */ | 720 | * presumes a floating bus reads as 0xff. */ |
632 | if ((inb(current_readport + 2) == 0xFF) || | 721 | if ((inb(pcwd_private.io_addr + 2) == 0xFF) || |
633 | (inb(current_readport + 3) == 0xFF)) | 722 | (inb(pcwd_private.io_addr + 3) == 0xFF)) |
634 | r=PCWD_REVISION_A; | 723 | r=PCWD_REVISION_A; |
635 | spin_unlock(&io_lock); | 724 | spin_unlock(&pcwd_private.io_lock); |
636 | 725 | ||
637 | return r; | 726 | return r; |
638 | } | 727 | } |
639 | 728 | ||
640 | static inline char *get_firmware(void) | ||
641 | { | ||
642 | int one, ten, hund, minor; | ||
643 | char *ret; | ||
644 | |||
645 | ret = kmalloc(6, GFP_KERNEL); | ||
646 | if(ret == NULL) | ||
647 | return NULL; | ||
648 | |||
649 | if (set_command_mode()) { | ||
650 | one = send_isa_command(CMD_ISA_VERSION_INTEGER); | ||
651 | ten = send_isa_command(CMD_ISA_VERSION_TENTH); | ||
652 | hund = send_isa_command(CMD_ISA_VERSION_HUNDRETH); | ||
653 | minor = send_isa_command(CMD_ISA_VERSION_MINOR); | ||
654 | sprintf(ret, "%c.%c%c%c", one, ten, hund, minor); | ||
655 | } | ||
656 | else | ||
657 | sprintf(ret, "ERROR"); | ||
658 | |||
659 | unset_command_mode(); | ||
660 | return(ret); | ||
661 | } | ||
662 | |||
663 | static inline int get_option_switches(void) | ||
664 | { | ||
665 | int rv=0; | ||
666 | |||
667 | if (set_command_mode()) { | ||
668 | /* Get switch settings */ | ||
669 | rv = send_isa_command(CMD_ISA_SWITCH_SETTINGS); | ||
670 | } | ||
671 | |||
672 | unset_command_mode(); | ||
673 | return(rv); | ||
674 | } | ||
675 | |||
676 | static int __devinit pcwatchdog_init(int base_addr) | 729 | static int __devinit pcwatchdog_init(int base_addr) |
677 | { | 730 | { |
678 | int ret; | 731 | int ret; |
679 | char *firmware; | ||
680 | int option_switches; | ||
681 | 732 | ||
682 | cards_found++; | 733 | cards_found++; |
683 | if (cards_found == 1) | 734 | if (cards_found == 1) |
@@ -692,104 +743,66 @@ static int __devinit pcwatchdog_init(int base_addr) | |||
692 | printk(KERN_ERR PFX "No I/O-Address for card detected\n"); | 743 | printk(KERN_ERR PFX "No I/O-Address for card detected\n"); |
693 | return -ENODEV; | 744 | return -ENODEV; |
694 | } | 745 | } |
695 | current_readport = base_addr; | 746 | pcwd_private.io_addr = base_addr; |
696 | 747 | ||
697 | /* Check card's revision */ | 748 | /* Check card's revision */ |
698 | revision = get_revision(); | 749 | pcwd_private.revision = get_revision(); |
699 | 750 | ||
700 | if (!request_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { | 751 | if (!request_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4, "PCWD")) { |
701 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", | 752 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", |
702 | current_readport); | 753 | pcwd_private.io_addr); |
703 | current_readport = 0x0000; | 754 | pcwd_private.io_addr = 0x0000; |
704 | return -EIO; | 755 | return -EIO; |
705 | } | 756 | } |
706 | 757 | ||
707 | /* Initial variables */ | 758 | /* Initial variables */ |
708 | supports_temp = 0; | 759 | pcwd_private.supports_temp = 0; |
709 | temp_panic = 0; | 760 | temp_panic = 0; |
710 | initial_status = 0x0000; | 761 | pcwd_private.boot_status = 0x0000; |
711 | 762 | ||
712 | /* get the boot_status */ | 763 | /* get the boot_status */ |
713 | pcwd_get_status(&initial_status); | 764 | pcwd_get_status(&pcwd_private.boot_status); |
714 | 765 | ||
715 | /* clear the "card caused reboot" flag */ | 766 | /* clear the "card caused reboot" flag */ |
716 | pcwd_clear_status(); | 767 | pcwd_clear_status(); |
717 | 768 | ||
718 | init_timer(&timer); | 769 | init_timer(&pcwd_private.timer); |
719 | timer.function = pcwd_timer_ping; | 770 | pcwd_private.timer.function = pcwd_timer_ping; |
720 | timer.data = 0; | 771 | pcwd_private.timer.data = 0; |
721 | 772 | ||
722 | /* Disable the board */ | 773 | /* Disable the board */ |
723 | pcwd_stop(); | 774 | pcwd_stop(); |
724 | 775 | ||
725 | /* Check whether or not the card supports the temperature device */ | 776 | /* Check whether or not the card supports the temperature device */ |
726 | get_support(); | 777 | pcwd_check_temperature_support(); |
727 | |||
728 | /* Get some extra info from the hardware (in command/debug/diag mode) */ | ||
729 | if (revision == PCWD_REVISION_A) | ||
730 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.A) detected at port 0x%04x\n", current_readport); | ||
731 | else if (revision == PCWD_REVISION_C) { | ||
732 | firmware = get_firmware(); | ||
733 | printk(KERN_INFO PFX "ISA-PC Watchdog (REV.C) detected at port 0x%04x (Firmware version: %s)\n", | ||
734 | current_readport, firmware); | ||
735 | kfree(firmware); | ||
736 | option_switches = get_option_switches(); | ||
737 | printk(KERN_INFO PFX "Option switches (0x%02x): Temperature Reset Enable=%s, Power On Delay=%s\n", | ||
738 | option_switches, | ||
739 | ((option_switches & 0x10) ? "ON" : "OFF"), | ||
740 | ((option_switches & 0x08) ? "ON" : "OFF")); | ||
741 | |||
742 | /* Reprogram internal heartbeat to 2 seconds */ | ||
743 | if (set_command_mode()) { | ||
744 | send_isa_command(CMD_ISA_DELAY_TIME_2SECS); | ||
745 | unset_command_mode(); | ||
746 | } | ||
747 | } else { | ||
748 | /* Should NEVER happen, unless get_revision() fails. */ | ||
749 | printk(KERN_INFO PFX "Unable to get revision\n"); | ||
750 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | ||
751 | current_readport = 0x0000; | ||
752 | return -1; | ||
753 | } | ||
754 | 778 | ||
755 | if (supports_temp) | 779 | /* Show info about the card itself */ |
756 | printk(KERN_INFO PFX "Temperature Option Detected\n"); | 780 | pcwd_show_card_info(); |
757 | |||
758 | if (initial_status & WDIOF_CARDRESET) | ||
759 | printk(KERN_INFO PFX "Previous reboot was caused by the card\n"); | ||
760 | |||
761 | if (initial_status & WDIOF_OVERHEAT) { | ||
762 | printk(KERN_EMERG PFX "Card senses a CPU Overheat. Panicking!\n"); | ||
763 | printk(KERN_EMERG PFX "CPU Overheat\n"); | ||
764 | } | ||
765 | |||
766 | if (initial_status == 0) | ||
767 | printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); | ||
768 | 781 | ||
769 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 782 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ |
770 | if (pcwd_set_heartbeat(heartbeat)) { | 783 | if (pcwd_set_heartbeat(heartbeat)) { |
771 | pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); | 784 | pcwd_set_heartbeat(WATCHDOG_HEARTBEAT); |
772 | printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", | 785 | printk(KERN_INFO PFX "heartbeat value must be 2<=heartbeat<=7200, using %d\n", |
773 | WATCHDOG_HEARTBEAT); | 786 | WATCHDOG_HEARTBEAT); |
774 | } | 787 | } |
775 | 788 | ||
776 | ret = register_reboot_notifier(&pcwd_notifier); | 789 | ret = register_reboot_notifier(&pcwd_notifier); |
777 | if (ret) { | 790 | if (ret) { |
778 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", | 791 | printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", |
779 | ret); | 792 | ret); |
780 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | 793 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
781 | current_readport = 0x0000; | 794 | pcwd_private.io_addr = 0x0000; |
782 | return ret; | 795 | return ret; |
783 | } | 796 | } |
784 | 797 | ||
785 | if (supports_temp) { | 798 | if (pcwd_private.supports_temp) { |
786 | ret = misc_register(&temp_miscdev); | 799 | ret = misc_register(&temp_miscdev); |
787 | if (ret) { | 800 | if (ret) { |
788 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 801 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", |
789 | TEMP_MINOR, ret); | 802 | TEMP_MINOR, ret); |
790 | unregister_reboot_notifier(&pcwd_notifier); | 803 | unregister_reboot_notifier(&pcwd_notifier); |
791 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | 804 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
792 | current_readport = 0x0000; | 805 | pcwd_private.io_addr = 0x0000; |
793 | return ret; | 806 | return ret; |
794 | } | 807 | } |
795 | } | 808 | } |
@@ -798,11 +811,11 @@ static int __devinit pcwatchdog_init(int base_addr) | |||
798 | if (ret) { | 811 | if (ret) { |
799 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 812 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", |
800 | WATCHDOG_MINOR, ret); | 813 | WATCHDOG_MINOR, ret); |
801 | if (supports_temp) | 814 | if (pcwd_private.supports_temp) |
802 | misc_deregister(&temp_miscdev); | 815 | misc_deregister(&temp_miscdev); |
803 | unregister_reboot_notifier(&pcwd_notifier); | 816 | unregister_reboot_notifier(&pcwd_notifier); |
804 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | 817 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
805 | current_readport = 0x0000; | 818 | pcwd_private.io_addr = 0x0000; |
806 | return ret; | 819 | return ret; |
807 | } | 820 | } |
808 | 821 | ||
@@ -820,11 +833,12 @@ static void __devexit pcwatchdog_exit(void) | |||
820 | 833 | ||
821 | /* Deregister */ | 834 | /* Deregister */ |
822 | misc_deregister(&pcwd_miscdev); | 835 | misc_deregister(&pcwd_miscdev); |
823 | if (supports_temp) | 836 | if (pcwd_private.supports_temp) |
824 | misc_deregister(&temp_miscdev); | 837 | misc_deregister(&temp_miscdev); |
825 | unregister_reboot_notifier(&pcwd_notifier); | 838 | unregister_reboot_notifier(&pcwd_notifier); |
826 | release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4); | 839 | release_region(pcwd_private.io_addr, (pcwd_private.revision == PCWD_REVISION_A) ? 2 : 4); |
827 | current_readport = 0x0000; | 840 | pcwd_private.io_addr = 0x0000; |
841 | cards_found--; | ||
828 | } | 842 | } |
829 | 843 | ||
830 | /* | 844 | /* |
@@ -887,7 +901,7 @@ static int __init pcwd_init_module(void) | |||
887 | { | 901 | { |
888 | int i, found = 0; | 902 | int i, found = 0; |
889 | 903 | ||
890 | spin_lock_init(&io_lock); | 904 | spin_lock_init(&pcwd_private.io_lock); |
891 | 905 | ||
892 | for (i = 0; pcwd_ioports[i] != 0; i++) { | 906 | for (i = 0; pcwd_ioports[i] != 0; i++) { |
893 | if (pcwd_checkcard(pcwd_ioports[i])) { | 907 | if (pcwd_checkcard(pcwd_ioports[i])) { |
@@ -906,7 +920,7 @@ static int __init pcwd_init_module(void) | |||
906 | 920 | ||
907 | static void __exit pcwd_cleanup_module(void) | 921 | static void __exit pcwd_cleanup_module(void) |
908 | { | 922 | { |
909 | if (current_readport) | 923 | if (pcwd_private.io_addr) |
910 | pcwatchdog_exit(); | 924 | pcwatchdog_exit(); |
911 | return; | 925 | return; |
912 | } | 926 | } |
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c index b474ea52d6e8..522a9370db94 100644 --- a/drivers/char/watchdog/sa1100_wdt.c +++ b/drivers/char/watchdog/sa1100_wdt.c | |||
@@ -93,23 +93,25 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, | |||
93 | { | 93 | { |
94 | int ret = -ENOIOCTLCMD; | 94 | int ret = -ENOIOCTLCMD; |
95 | int time; | 95 | int time; |
96 | void __user *argp = (void __user *)arg; | ||
97 | int __user *p = argp; | ||
96 | 98 | ||
97 | switch (cmd) { | 99 | switch (cmd) { |
98 | case WDIOC_GETSUPPORT: | 100 | case WDIOC_GETSUPPORT: |
99 | ret = copy_to_user((struct watchdog_info __user *)arg, &ident, | 101 | ret = copy_to_user(argp, &ident, |
100 | sizeof(ident)) ? -EFAULT : 0; | 102 | sizeof(ident)) ? -EFAULT : 0; |
101 | break; | 103 | break; |
102 | 104 | ||
103 | case WDIOC_GETSTATUS: | 105 | case WDIOC_GETSTATUS: |
104 | ret = put_user(0, (int __user *)arg); | 106 | ret = put_user(0, p); |
105 | break; | 107 | break; |
106 | 108 | ||
107 | case WDIOC_GETBOOTSTATUS: | 109 | case WDIOC_GETBOOTSTATUS: |
108 | ret = put_user(boot_status, (int __user *)arg); | 110 | ret = put_user(boot_status, p); |
109 | break; | 111 | break; |
110 | 112 | ||
111 | case WDIOC_SETTIMEOUT: | 113 | case WDIOC_SETTIMEOUT: |
112 | ret = get_user(time, (int __user *)arg); | 114 | ret = get_user(time, p); |
113 | if (ret) | 115 | if (ret) |
114 | break; | 116 | break; |
115 | 117 | ||
@@ -123,7 +125,7 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file, | |||
123 | /*fall through*/ | 125 | /*fall through*/ |
124 | 126 | ||
125 | case WDIOC_GETTIMEOUT: | 127 | case WDIOC_GETTIMEOUT: |
126 | ret = put_user(pre_margin / OSCR_FREQ, (int __user *)arg); | 128 | ret = put_user(pre_margin / OSCR_FREQ, p); |
127 | break; | 129 | break; |
128 | 130 | ||
129 | case WDIOC_KEEPALIVE: | 131 | case WDIOC_KEEPALIVE: |
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c index 7a4dfb95d087..837b1ec3ffe3 100644 --- a/drivers/char/watchdog/sbc_epx_c3.c +++ b/drivers/char/watchdog/sbc_epx_c3.c | |||
@@ -92,7 +92,7 @@ static int epx_c3_release(struct inode *inode, struct file *file) | |||
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
94 | 94 | ||
95 | static ssize_t epx_c3_write(struct file *file, const char *data, | 95 | static ssize_t epx_c3_write(struct file *file, const char __user *data, |
96 | size_t len, loff_t *ppos) | 96 | size_t len, loff_t *ppos) |
97 | { | 97 | { |
98 | /* Refresh the timer. */ | 98 | /* Refresh the timer. */ |
@@ -105,6 +105,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
105 | unsigned int cmd, unsigned long arg) | 105 | unsigned int cmd, unsigned long arg) |
106 | { | 106 | { |
107 | int options, retval = -EINVAL; | 107 | int options, retval = -EINVAL; |
108 | int __user *argp = (void __user *)arg; | ||
108 | static struct watchdog_info ident = { | 109 | static struct watchdog_info ident = { |
109 | .options = WDIOF_KEEPALIVEPING | | 110 | .options = WDIOF_KEEPALIVEPING | |
110 | WDIOF_MAGICCLOSE, | 111 | WDIOF_MAGICCLOSE, |
@@ -114,20 +115,19 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
114 | 115 | ||
115 | switch (cmd) { | 116 | switch (cmd) { |
116 | case WDIOC_GETSUPPORT: | 117 | case WDIOC_GETSUPPORT: |
117 | if (copy_to_user((struct watchdog_info *)arg, | 118 | if (copy_to_user(argp, &ident, sizeof(ident))) |
118 | &ident, sizeof(ident))) | ||
119 | return -EFAULT; | 119 | return -EFAULT; |
120 | return 0; | 120 | return 0; |
121 | case WDIOC_GETSTATUS: | 121 | case WDIOC_GETSTATUS: |
122 | case WDIOC_GETBOOTSTATUS: | 122 | case WDIOC_GETBOOTSTATUS: |
123 | return put_user(0,(int *)arg); | 123 | return put_user(0, argp); |
124 | case WDIOC_KEEPALIVE: | 124 | case WDIOC_KEEPALIVE: |
125 | epx_c3_pet(); | 125 | epx_c3_pet(); |
126 | return 0; | 126 | return 0; |
127 | case WDIOC_GETTIMEOUT: | 127 | case WDIOC_GETTIMEOUT: |
128 | return put_user(WATCHDOG_TIMEOUT,(int *)arg); | 128 | return put_user(WATCHDOG_TIMEOUT, argp); |
129 | case WDIOC_SETOPTIONS: { | 129 | case WDIOC_SETOPTIONS: |
130 | if (get_user(options, (int *)arg)) | 130 | if (get_user(options, argp)) |
131 | return -EFAULT; | 131 | return -EFAULT; |
132 | 132 | ||
133 | if (options & WDIOS_DISABLECARD) { | 133 | if (options & WDIOS_DISABLECARD) { |
@@ -141,7 +141,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
141 | } | 141 | } |
142 | 142 | ||
143 | return retval; | 143 | return retval; |
144 | } | ||
145 | default: | 144 | default: |
146 | return -ENOIOCTLCMD; | 145 | return -ENOIOCTLCMD; |
147 | } | 146 | } |