[parisc-linux-cvs] LCD/LED patch which fixes c3k-crashes

Helge Deller deller@gmx.de
Wed, 6 Jun 2001 21:57:17 +0200


- EXTRAVERSION = -pa12
- CONFIG_CHASSIS_LCD_LED=y crashed the c3000 (and presumely others too) at 
boot.
The good thing is: This patch prevents those machines from crashing and should
still work on machines where the LCD/LED code worked before.
The bad thing: The LCD will not be used on those "bad" machines atm, since 
PDC seems to return none, wrong and/or incomplete values.

Index: Makefile
===================================================================
RCS file: /home/cvs/parisc/linux/Makefile,v
retrieving revision 1.44
diff -u -r1.44 Makefile
--- Makefile	2001/06/06 18:24:31	1.44
+++ Makefile	2001/06/06 19:25:30
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -pa11
+EXTRAVERSION = -pa12
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: led.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/led.c,v
retrieving revision 1.17
diff -u -r1.17 led.c
--- led.c	2001/04/06 05:10:54	1.17
+++ led.c	2001/06/06 19:26:10
@@ -20,6 +20,7 @@
 #define DEBUG 1	/* undefine for production */
 
 #include <linux/config.h>
+#include <linux/stddef.h>	/* for offsetof() */
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
@@ -158,8 +159,6 @@
 	static int last_was_cmd;/* 0: CMD was written last, 1: DATA was last */
 	struct lcd_block *block_ptr;
 	int value;
-	
- 	// leds = ~leds;	/* needed ? */ 
 
 	switch (last_index) {
 	    case 0:	block_ptr = &lcd_info.heartbeat;
@@ -504,18 +503,19 @@
 		break;
 	}
 
-	/* initialize raddr, so we can check the return values of 
pdc_chassis_info() */
+	/* initialize the struct, so that we can check for valid return values */
+	lcd_info.model = DISPLAY_MODEL_NONE;
 	chassis_info.actcnt = chassis_info.maxcnt = 0;
 
 	if (pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info)) == PDC_OK) 
{
 		pr_debug("%s: chassis info: model=%d (%s), "
-			 "lcd_width=%d, cmd_delay=%u, actcnt=%ld, maxcnt=%ld\n",
-		         __FUNCTION__,
-			 lcd_info.model, 
+			 "lcd_width=%d, cmd_delay=%u, "
+			 "sizecnt=%d, actcnt=%ld, maxcnt=%ld\n",
+		         __FUNCTION__, lcd_info.model, 
 			 (lcd_info.model==DISPLAY_MODEL_LCD) ? "LCD" :
 			  (lcd_info.model==DISPLAY_MODEL_LASI) ? "LED" : "unknown",  
-			 lcd_info.lcd_width, lcd_info.min_cmd_delay, 
-			 chassis_info.actcnt, chassis_info.maxcnt);
+			 lcd_info.lcd_width, lcd_info.min_cmd_delay,
+			 sizeof(lcd_info), chassis_info.actcnt, chassis_info.maxcnt);
 
 		/* check the results. Some machines have a buggy PDC */
 		if (chassis_info.actcnt <= 0 || chassis_info.actcnt != chassis_info.maxcnt)
@@ -524,13 +524,12 @@
 		switch (lcd_info.model) {
 		case DISPLAY_MODEL_LCD:		/* LCD display */
 			if (chassis_info.actcnt < 
-			    (unsigned long)&lcd_info._pad - (unsigned long)&lcd_info - 1)
-				 goto not_found;
-			pr_debug("%s: min_cmd_delay = %d uS\n",
-		             __FUNCTION__, lcd_info.min_cmd_delay);
+				offsetof(struct pdc_chassis_lcd_info_ret_block, _pad)-1)
+				goto not_found;
 			break;
 
 		case DISPLAY_MODEL_NONE:	/* no LED or LCD available */
+			printk(KERN_INFO "PDC reported no LCD or LED.\n");
 			goto not_found;
 
 		case DISPLAY_MODEL_LASI:	/* Lasi style 8 bit LED display */