i386/73380: [patch] kldload acpi_asus.ko causes page fault on Samsung P35

Sebastian Schulze Struchtrup sebastian at struchtrup.de
Thu Nov 4 05:18:48 PST 2004


Philip Paeps wrote:

>On 2004-11-01 14:14:41 (+0100), Sebastian Schulze Struchtrup <sebastian at struchtrup.de> wrote:
>  
>
>>Well, the patch got lost.
>>Here it is.
>>    
>>
>
>Does this patch work for you?  I think it's a bit simpler than yours, and it
>should accomplish the same thing.  It also doesn't break style(9) quite so
>dramatically ;-)
>  
>
Not yet. It is rather Obj->String.Pointer which is NULL, not Obj itself.
After changing this, it works.
I think I have had both checks in my patch, with the one being redundant.
Thanks for handling this!

The corrected patch is attached.

-------------- next part --------------
Index: acpi_asus.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/acpica/acpi_asus.c,v
retrieving revision 1.12
diff -u -p -r1.12 acpi_asus.c
--- acpi_asus.c	2 Nov 2004 13:02:22 -0000	1.12
+++ acpi_asus.c	4 Nov 2004 13:13:29 -0000
@@ -102,7 +102,10 @@ struct acpi_asus_softc {
 	int			s_lcd;
 };
 
-/* Models we know about */
+/*
+ * We can identify Asus laptops from the string they return
+ * as a result of calling the ATK0100 'INIT' method.
+ */
 static struct acpi_asus_model acpi_asus_models[] = {
 	{
 		.name		= "L2D",
@@ -174,6 +177,15 @@ static struct acpi_asus_model acpi_asus_
 		.disp_set	= "SDSP",
 		.disp_get	= "\\SSTE"
 	},
+
+	{ .name = NULL }
+};
+
+/*
+ * Samsung P30/P35 laptops have an Asus ATK0100 gadget interface,
+ * but they can't be probed quite the same way as Asus laptops.
+ */
+static struct acpi_asus_model acpi_samsung_models[] = {
 	{
 		.name		= "P30",
 		.wled_set	= "WLED",
@@ -254,13 +266,48 @@ acpi_asus_probe(device_t dev)
 		Buf.Length = ACPI_ALLOCATE_BUFFER;
 	
 		AcpiEvaluateObject(sc->handle, "INIT", &Args, &Buf);
-		
 		Obj = Buf.Pointer;
 
+		/*
+		 * The Samsung P30 returns a null-pointer from INIT, we
+		 * can identify it from the 'ODEM' string in the DSDT.
+		 */
+		if (Obj->String.Pointer == NULL) {
+			ACPI_STATUS		status;
+			ACPI_TABLE_HEADER	th;
+
+			status = AcpiGetTableHeader(ACPI_TABLE_DSDT, 1, &th);
+			if (ACPI_FAILURE(status)) {
+				sbuf_printf(sb, "Unsupported laptop\n");
+				sbuf_finish(sb);
+
+				device_printf(dev, sbuf_data(sb));
+
+				sbuf_delete(sb);
+				AcpiOsFree(Buf.Pointer);
+				return (ENXIO);
+			}
+
+			if (strncmp("ODEM", th.OemTableId, 4) == 0) {
+				sbuf_printf(sb, "Samsung P30 Laptop Extras");
+				sbuf_finish(sb);
+
+				sc->model = &acpi_samsung_models[0];
+				device_set_desc(dev, sbuf_data(sb));
+
+				sbuf_delete(sb);
+				AcpiOsFree(Buf.Pointer);
+				return (0);
+			}
+		}
+
+		/*
+		 * Asus laptops are simply identified by name, easy!
+		 */
 		for (model = acpi_asus_models; model->name != NULL; model++)
 			if (strcmp(Obj->String.Pointer, model->name) == 0) {
 				sbuf_printf(sb, "Asus %s Laptop Extras",
-						Obj->String.Pointer);
+				    Obj->String.Pointer);
 				sbuf_finish(sb);
 				
 				sc->model = model;
@@ -272,7 +319,7 @@ acpi_asus_probe(device_t dev)
 			}
 
 		sbuf_printf(sb, "Unsupported Asus laptop detected: %s\n",
-				Obj->String.Pointer);
+		    Obj->String.Pointer);
 		sbuf_finish(sb);
 
 		device_printf(dev, sbuf_data(sb));


More information about the freebsd-acpi mailing list