diff options
author | Miguel Ojeda <maxextreme@gmail.com> | 2007-02-20 16:58:00 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-20 20:10:14 -0500 |
commit | 34173a4aad7a641e72b70f9927ca797746fbce69 (patch) | |
tree | e09d2fd33dc6e14d4b76210e471c47e8fed7b2a1 | |
parent | e627432c2948d500669a6c4522f22b66f5118d64 (diff) |
[PATCH] cfag12864b: fix crash when built-in and no parport present
The problem comes when ks0108/cfag12864b are built-in and no parallel port is
present. ks0108_init() is called first, as it should be, but fails to load
(as there is no parallel port to use).
After that, cfag12864b_init() gets called, without knowing anything about
ks0108 failed, and calls ks0108_writecontrol(), which dereferences an
uninitialized pointer.
Init order is OK, I think. The problem is how to stop cfag12864b_init() being
called if ks0108 failed to load. modprobe does it for us, but, how when
built-in?
Signed-off-by: Miguel Ojeda Sandonis <maxextreme@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/auxdisplay/cfag12864b.c | 19 | ||||
-rw-r--r-- | drivers/auxdisplay/cfag12864bfb.c | 10 | ||||
-rw-r--r-- | drivers/auxdisplay/ks0108.c | 12 | ||||
-rw-r--r-- | include/linux/cfag12864b.h | 5 | ||||
-rw-r--r-- | include/linux/ks0108.h | 3 |
5 files changed, 48 insertions, 1 deletions
diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index 889583dfc1a6..cb44cb4f6a47 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c | |||
@@ -312,6 +312,17 @@ EXPORT_SYMBOL_GPL(cfag12864b_disable); | |||
312 | EXPORT_SYMBOL_GPL(cfag12864b_isenabled); | 312 | EXPORT_SYMBOL_GPL(cfag12864b_isenabled); |
313 | 313 | ||
314 | /* | 314 | /* |
315 | * Is the module inited? | ||
316 | */ | ||
317 | |||
318 | static unsigned char cfag12864b_inited; | ||
319 | unsigned char cfag12864b_isinited(void) | ||
320 | { | ||
321 | return cfag12864b_inited; | ||
322 | } | ||
323 | EXPORT_SYMBOL_GPL(cfag12864b_isinited); | ||
324 | |||
325 | /* | ||
315 | * Module Init & Exit | 326 | * Module Init & Exit |
316 | */ | 327 | */ |
317 | 328 | ||
@@ -319,6 +330,13 @@ static int __init cfag12864b_init(void) | |||
319 | { | 330 | { |
320 | int ret = -EINVAL; | 331 | int ret = -EINVAL; |
321 | 332 | ||
333 | /* ks0108_init() must be called first */ | ||
334 | if (!ks0108_isinited()) { | ||
335 | printk(KERN_ERR CFAG12864B_NAME ": ERROR: " | ||
336 | "ks0108 is not initialized\n"); | ||
337 | goto none; | ||
338 | } | ||
339 | |||
322 | if (PAGE_SIZE < CFAG12864B_SIZE) { | 340 | if (PAGE_SIZE < CFAG12864B_SIZE) { |
323 | printk(KERN_ERR CFAG12864B_NAME ": ERROR: " | 341 | printk(KERN_ERR CFAG12864B_NAME ": ERROR: " |
324 | "page size (%i) < cfag12864b size (%i)\n", | 342 | "page size (%i) < cfag12864b size (%i)\n", |
@@ -354,6 +372,7 @@ static int __init cfag12864b_init(void) | |||
354 | cfag12864b_clear(); | 372 | cfag12864b_clear(); |
355 | cfag12864b_on(); | 373 | cfag12864b_on(); |
356 | 374 | ||
375 | cfag12864b_inited = 1; | ||
357 | return 0; | 376 | return 0; |
358 | 377 | ||
359 | cachealloced: | 378 | cachealloced: |
diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c index 94765e78315f..66fafbb1d087 100644 --- a/drivers/auxdisplay/cfag12864bfb.c +++ b/drivers/auxdisplay/cfag12864bfb.c | |||
@@ -137,7 +137,14 @@ static struct platform_device *cfag12864bfb_device; | |||
137 | 137 | ||
138 | static int __init cfag12864bfb_init(void) | 138 | static int __init cfag12864bfb_init(void) |
139 | { | 139 | { |
140 | int ret; | 140 | int ret = -EINVAL; |
141 | |||
142 | /* cfag12864b_init() must be called first */ | ||
143 | if (!cfag12864b_isinited()) { | ||
144 | printk(KERN_ERR CFAG12864BFB_NAME ": ERROR: " | ||
145 | "cfag12864b is not initialized\n"); | ||
146 | goto none; | ||
147 | } | ||
141 | 148 | ||
142 | if (cfag12864b_enable()) { | 149 | if (cfag12864b_enable()) { |
143 | printk(KERN_ERR CFAG12864BFB_NAME ": ERROR: " | 150 | printk(KERN_ERR CFAG12864BFB_NAME ": ERROR: " |
@@ -162,6 +169,7 @@ static int __init cfag12864bfb_init(void) | |||
162 | } | 169 | } |
163 | } | 170 | } |
164 | 171 | ||
172 | none: | ||
165 | return ret; | 173 | return ret; |
166 | } | 174 | } |
167 | 175 | ||
diff --git a/drivers/auxdisplay/ks0108.c b/drivers/auxdisplay/ks0108.c index a637575b9106..e6c3646ef18c 100644 --- a/drivers/auxdisplay/ks0108.c +++ b/drivers/auxdisplay/ks0108.c | |||
@@ -111,6 +111,17 @@ EXPORT_SYMBOL_GPL(ks0108_address); | |||
111 | EXPORT_SYMBOL_GPL(ks0108_page); | 111 | EXPORT_SYMBOL_GPL(ks0108_page); |
112 | 112 | ||
113 | /* | 113 | /* |
114 | * Is the module inited? | ||
115 | */ | ||
116 | |||
117 | static unsigned char ks0108_inited; | ||
118 | unsigned char ks0108_isinited(void) | ||
119 | { | ||
120 | return ks0108_inited; | ||
121 | } | ||
122 | EXPORT_SYMBOL_GPL(ks0108_isinited); | ||
123 | |||
124 | /* | ||
114 | * Module Init & Exit | 125 | * Module Init & Exit |
115 | */ | 126 | */ |
116 | 127 | ||
@@ -142,6 +153,7 @@ static int __init ks0108_init(void) | |||
142 | goto registered; | 153 | goto registered; |
143 | } | 154 | } |
144 | 155 | ||
156 | ks0108_inited = 1; | ||
145 | return 0; | 157 | return 0; |
146 | 158 | ||
147 | registered: | 159 | registered: |
diff --git a/include/linux/cfag12864b.h b/include/linux/cfag12864b.h index 0bc45e69da5a..1605dd8aa646 100644 --- a/include/linux/cfag12864b.h +++ b/include/linux/cfag12864b.h | |||
@@ -73,5 +73,10 @@ extern void cfag12864b_disable(void); | |||
73 | */ | 73 | */ |
74 | extern unsigned char cfag12864b_isenabled(void); | 74 | extern unsigned char cfag12864b_isenabled(void); |
75 | 75 | ||
76 | /* | ||
77 | * Is the module inited? | ||
78 | */ | ||
79 | extern unsigned char cfag12864b_isinited(void); | ||
80 | |||
76 | #endif /* _CFAG12864B_H_ */ | 81 | #endif /* _CFAG12864B_H_ */ |
77 | 82 | ||
diff --git a/include/linux/ks0108.h b/include/linux/ks0108.h index 8047d4b17bf1..a2c54acceb4e 100644 --- a/include/linux/ks0108.h +++ b/include/linux/ks0108.h | |||
@@ -43,4 +43,7 @@ extern void ks0108_address(unsigned char address); | |||
43 | /* Set the controller's current page (0..7) */ | 43 | /* Set the controller's current page (0..7) */ |
44 | extern void ks0108_page(unsigned char page); | 44 | extern void ks0108_page(unsigned char page); |
45 | 45 | ||
46 | /* Is the module inited? */ | ||
47 | extern unsigned char ks0108_isinited(void); | ||
48 | |||
46 | #endif /* _KS0108_H_ */ | 49 | #endif /* _KS0108_H_ */ |