• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] ACPI Problem mit OpenSuse 10 auf Samsung P35

Status
Für weitere Antworten geschlossen.

proweso

Newbie
Nach einer Neuinstallation von Suse 10.0 funktioniert das WLAN nicht mehr (Signalstärke=0) und die Beleuchtungseinstellung über die FN-Keys läuft extrem langsam ab.

Bisher hatte ich Suse 9.2-Pro installiert. Dort lief soweit alles ohne Probleme.

Wenn ich unter 10.0 am Bootprompt "acpi=off" oder "acpi=oldboot" eingebe läuft das WLAN einwandfrei und die Beleuchtung flüssig. Dafür geht die Batterieanzeige nicht mehr (zeigt immer Netzbetrieb). Beim Shutdown bleibt der Rechner hängen.

Bei "apm=off" oder "pci=noacpi" geht weder WLAN noch Batterieanzeige und Beleuchtung klemmt auch noch.

Hat jemand eine Idee wie man das in den Griff bekommt? Immerhin hat es ja unter Suse 9.2 einwandfrei funktioniert.
 
Du solltest einen ec_burst-Patch einspielen und den Kernel damit neu compilieren.
Damit du nicht lange suchen musst, habe ich ihn dir angehängt:
Code:
--- ec.c.0	2005-08-10 10:20:15.000000000 +0800
+++ ec.c	2005-08-10 11:25:59.000000000 +0800
@@ -234,18 +234,29 @@
 	ec->burst.expect_event = event;
 	smp_mb();
 
-	result = wait_event_interruptible_timeout(ec->burst.wait,
+	switch (event) {
+	case ACPI_EC_EVENT_OBF:
+		if (acpi_ec_read_status(ec) & event) {
+			ec->burst.expect_event = 0;
+			return_VALUE(0);
+		}
+		break;
+
+	case ACPI_EC_EVENT_IBE:
+		if (~acpi_ec_read_status(ec) & event) {
+			ec->burst.expect_event = 0;
+			return_VALUE(0);
+		}
+		break;
+	}
+
+	result = wait_event_timeout(ec->burst.wait,
 					!ec->burst.expect_event,
 					msecs_to_jiffies(ACPI_EC_DELAY));
 	
 	ec->burst.expect_event = 0;
 	smp_mb();
 
-	if (result < 0){
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result  = %d ", result));
-		return_VALUE(result);
-	}
-
 	/*
 	 * Verify that the event in question has actually happened by
 	 * querying EC status. Do the check even if operation timed-out
@@ -280,14 +291,14 @@
 	status = acpi_ec_read_status(ec);
 	if (status != -EINVAL &&
 		!(status & ACPI_EC_FLAG_BURST)){
+		status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+		if(status)
+			goto end;
 		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
 		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-		if (status){
-			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		if (status)
 			return_VALUE(-EINVAL);
-		}
 		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 		if(tmp != 0x90 ) {/* Burst ACK byte*/
 			return_VALUE(-EINVAL);
 		}
@@ -295,31 +306,19 @@
 
 	atomic_set(&ec->burst.leaving_burst , 0);
 	return_VALUE(0);
+end:
+	printk("Error in acpi_ec_wait\n");
+	return_VALUE(-1);
 }
 
 static int
 acpi_ec_leave_burst_mode (
 	union acpi_ec		*ec)
 {
-	int			status =0;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
 
-	atomic_set(&ec->burst.leaving_burst , 1);
-	status = acpi_ec_read_status(ec);
-	if (status != -EINVAL &&
-		(status & ACPI_EC_FLAG_BURST)){
-		acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
-		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
-		if (status){
-			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
-			return_VALUE(-EINVAL);
-		}
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		status = acpi_ec_read_status(ec);
-	}
-
+	atomic_set(&ec->burst.leaving_burst, 1);
 	return_VALUE(0);
 }
 
@@ -461,7 +460,6 @@
 	if (!ec || !data)
 		return_VALUE(-EINVAL);
 
-retry:
 	*data = 0;
 
 	if (ec->common.global_lock) {
@@ -473,26 +471,25 @@
 	WARN_ON(in_interrupt());
 	down(&ec->burst.sem);
 
-	if(acpi_ec_enter_burst_mode(ec))
+	acpi_ec_enter_burst_mode(ec);
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (status) {
+		printk("read EC, IB not empty\n");
 		goto end;
-
+	}
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 	if (status) {
-		goto end;
+		printk("read EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
 	status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (status){
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		printk("read EC, OB not full\n");
 		goto end;
 	}
-
 	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
 		*data, address));
 	
@@ -503,15 +500,6 @@
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
-	if(atomic_read(&ec->burst.leaving_burst) == 2){
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-		while(atomic_read(&ec->burst.pending_gpe)){
-			msleep(1);	
-		}
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		goto retry;
-	}
-
 	return_VALUE(status);
 }
 
@@ -524,13 +512,12 @@
 {
 	int			status = 0;
 	u32			glk;
-	u32			tmp;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_write");
 
 	if (!ec)
 		return_VALUE(-EINVAL);
-retry:
+
 	if (ec->common.global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
@@ -540,61 +527,35 @@
 	WARN_ON(in_interrupt());
 	down(&ec->burst.sem);
 
-	if(acpi_ec_enter_burst_mode(ec))
-		goto end;
+	acpi_ec_enter_burst_mode(ec);
 
-	status = acpi_ec_read_status(ec);
-	if (status != -EINVAL &&
-		!(status & ACPI_EC_FLAG_BURST)){
-		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
-		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-		if (status)
-			goto end;
-		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
-		if(tmp != 0x90 ) /* Burst ACK byte*/
-			goto end;
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if ( status) {
+		printk("write EC, IB not empty\n");
 	}
-	/*Now we are in burst mode*/
-
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-	if (status){
-		goto end;
+	if (status) {
+		printk ("write EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (status){
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		goto end;
+		printk("write EC, IB not empty\n");
 	}
 
 	acpi_hw_low_level_write(8, data, &ec->common.data_addr);
-	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-	if (status)
-		goto end;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
 		data, address));
 
-end:
 	acpi_ec_leave_burst_mode(ec);
 	up(&ec->burst.sem);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
-	if(atomic_read(&ec->burst.leaving_burst) == 2){
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-		while(atomic_read(&ec->burst.pending_gpe)){
-			msleep(1);	
-		}
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		goto retry;
-	}
-
 	return_VALUE(status);
 }
 
@@ -719,8 +680,12 @@
 	}
 
 	down(&ec->burst.sem);
-	if(acpi_ec_enter_burst_mode(ec))
+
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (status) {
+		printk("query EC, IB not empty\n");
 		goto end;
+	}
 	/*
 	 * Query the EC to find out which _Qxx method we need to evaluate.
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
@@ -729,27 +694,20 @@
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
 	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (status){
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		printk("query EC, OB not full\n");
 		goto end;
 	}
 
 	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
-	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 	if (!*data)
 		status = -ENODATA;
 
 end:
-	acpi_ec_leave_burst_mode(ec);
 	up(&ec->burst.sem);
 
 	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
-	if(atomic_read(&ec->burst.leaving_burst) == 2){
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
-		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
-		status = -ENODATA;
-	}
 	return_VALUE(status);
 }
 
@@ -885,31 +843,21 @@
 	if (!ec)
 		return ACPI_INTERRUPT_NOT_HANDLED;
 
-	acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
-
+	acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
 	value = acpi_ec_read_status(ec);
 
-	if((value & ACPI_EC_FLAG_IBF) &&
-		!(value & ACPI_EC_FLAG_BURST) &&
-			(atomic_read(&ec->burst.leaving_burst) == 0)) { 
-	/*
-	 * the embedded controller disables 
-	 * burst mode for any reason other 
-	 * than the burst disable command
-	 * to process critical event.
-	 */
-		atomic_set(&ec->burst.leaving_burst , 2); /* block current pending transaction
-					and retry */
+	switch ( ec->burst.expect_event) {
+	case ACPI_EC_EVENT_OBF:
+		if (!(value & ACPI_EC_FLAG_OBF))
+			break;
+	case ACPI_EC_EVENT_IBE:
+		if ((value & ACPI_EC_FLAG_IBF))
+			break;
+		ec->burst.expect_event = 0;
 		wake_up(&ec->burst.wait);
-	}else {
-		if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF &&
-				(value & ACPI_EC_FLAG_OBF)) ||
-	    			(ec->burst.expect_event == ACPI_EC_EVENT_IBE &&
-				!(value & ACPI_EC_FLAG_IBF))) {
-			ec->burst.expect_event = 0;
-			wake_up(&ec->burst.wait);
-			return ACPI_INTERRUPT_HANDLED;
-		}
+		return ACPI_INTERRUPT_HANDLED;
+	default:
+		break;
 	}
 
 	if (value & ACPI_EC_FLAG_SCI){
@@ -1242,6 +1190,7 @@
 	if (result)
 		goto end;
 
+	printk("burst-mode-ec-10-Aug\n");
 	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
 		acpi_device_name(device), acpi_device_bid(device),
 		(u32) ec->common.gpe_bit);

Greetz, HB
 
OP
proweso

proweso

Newbie
Nach einer Neuinstallation von Suse 10.0 funktioniert das WLAN nicht mehr (Signalstärke=0) und die Beleuchtungseinstellung über die FN-Keys läuft extrem langsam ab.
Nach einem Jahr mit dem P35 hab ich festgestellt, dass WLAN über einen Special-Key ein-/ausgeschaltet werden kann. Bei Suse 9.3 lief WLAN immer und die Taste war ohne Funktion. Unter Suse 10 geht sie und ist nach dem Booten ausgeschaltet. :oops:

Also: WLAN funktioniert! :D

Es bleibt das Problem mit dem verzögerten Verhalten der Special-Keys (WLAN-Key, Display-Beleuchtung). Ich hoffe der Patch von Hans Bauer bringt eine Besserung (Danke vorab). Konnte es noch nicht ausprobieren, werde aber einen Statusbericht hier posten.

Die Key-Verzögerung hat ein gewisses System. Es sieht so aus, als ob die Key-Events in einer Art Ringbuffer auflaufen. Wenn ich den WLAN-Key drücke, passiert erstmal garnichts. Erst wenn ich 7x einen anderen Specialkey betätige, wird die WLAN-Aktion ausgeführt. Beim nächsten Keypress wird dann der erste der vorherigen 7 ausgelöst usw...
Im Notfall kann man damit Leben:
WLAN ein: 1xWLAN + 7xINFO Key
WLAN aus: 1xWLAN + 7xINFO Key

Gruß,
Andreas
 
OP
proweso

proweso

Newbie
Hab soeben den Patch von Hans installiert und siehe da, die Sondertasten funktionieren wieder ohne Probleme :D.

Für alle, die auch das ACPI-Problem haben und wie ich keine Kernel-Patch-Profis sind:

Hier eine Mini-Anleitung für OpenSuse 10.0:

1. Kernel-Sourcen, gcc und make mit Yast installieren
Yast starten und dann "Software installieren oder löschen" auswählen. Suchen nach "kernel-source", "gcc" und "make". Ggf. nachinstallieren.

2. Den Patch-Code (s.o.) in einer Datei auf dem Rechner speichern.
Ich habe ihn unter /root/acpi/ec.diff abgelegt. Vorher mit CTRL-C hier ausgeschnitten und in eine Editor per CTRL-V eingefügt.

3. Den Patch von der Konsole aus einspielen:
Code:
cd /usr/src/linux/drivers/acpi/
patch -l ./ec.c  <pfad_zum_patch>/ec.diff  # <pfad_zu_patch> bei mir: /root/acpi
Wichtig ist die Option -l beim patch-Kommando ("l" = "kleines L").

4. Neuen Kernel erstellen (das 'make' dauert eine halbe Ewigkeit):
Code:
cd /usr/src/linux/
make cloneconfig # oder menuconfig oder oldconfig oder xconfig
make
make module_install

5. Reboot und dann sollte es gehen.

Vielen Dank nochmal an Hans. Das hätte mich sonst etliche Nächte gekostet, falls ich es überhaupt gefunden hätte :wink:
 
Status
Für weitere Antworten geschlossen.
Oben