From seb@struchtrup.com  Mon Nov  1 12:59:26 2004
Return-Path: <seb@struchtrup.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP
	id 3080916A4CE; Mon,  1 Nov 2004 12:59:26 +0000 (GMT)
Received: from mail.struchtrup.de (mail.struchtrup.de [80.190.247.172])
	by mx1.FreeBSD.org (Postfix) with ESMTP
	id 91D6143D31; Mon,  1 Nov 2004 12:59:21 +0000 (GMT)
	(envelope-from seb@struchtrup.com)
Received: from p5087c910.dip0.t-ipconnect.de ([80.135.201.16] helo=notebook.intranet.struchtrup.com)
	by mail.struchtrup.de with esmtpsa (TLSv1:AES256-SHA:256)
	(Exim 4.42 (FreeBSD))
	id 1CObmB-00044Y-MT; Mon, 01 Nov 2004 12:59:11 +0000
Received: from seb by notebook.intranet.struchtrup.com with local (Exim 4.43 (FreeBSD))
	id 1CObmK-000D37-02; Mon, 01 Nov 2004 13:59:20 +0100
Message-Id: <E1CObmK-000D37-02@notebook.intranet.struchtrup.com>
Date: Mon, 01 Nov 2004 13:59:20 +0100
From: Sebastian Schulze Struchtrup <seb@struchtrup.com>
Reply-To: Sebastian Schulze Struchtrup <seb@struchtrup.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc: acpi@freebsd.org, philip@freebsd.org
Subject: [patch] kldload acpi_asus.ko causes page fault on Samsung P35
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         73380
>Category:       i386
>Synopsis:       [patch] kldload acpi_asus.ko causes page fault on Samsung P35
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    philip
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov 01 13:00:40 GMT 2004
>Closed-Date:    Fri Nov 05 07:30:53 GMT 2004
>Last-Modified:  Fri Nov 05 07:30:53 GMT 2004
>Originator:     Sebastian Schulze Struchtrup
>Release:        FreeBSD 5.3-RC2 i386
>Organization:
>Environment:
System: FreeBSD notebook.intranet.struchtrup.com 5.3-RC2 FreeBSD 5.3-RC2 #6: Sun Oct 31 19:22:38 CET 2004 seb@notebook.intranet.struchtrup.com:/usr/obj/usr/src/sys/notebook i386
>Description:
The Samsung P30/P35 notebooks have an Asus ATK device.
But on ATK Init, they return a null pointer instead of a model identification.
This results in a page fault in acpi_asus_probe (strcmp againt null pointer)
The linux acpi4asus identifies them by an "ODEM" string as their DSDT Oem Table ID.

>How-To-Repeat:
>Fix:
I have modified the acpi_asus_probe function to identify the notebook via the "ODEM" string.
We have to see if this will work in the future or if there are other notebooks with the same string which require different handling.
At least the linux acpi4asus seems to work without problems with this approach.

Addionally, I have splitted the acpi_asus_models struct and added an extra struct acpi_asus_extra_models.
The first contains the models which are identified by their model identification (inside the for loop),
the second one contains models identified in another way  (currently, only the Samsung P30/35).
The enum acpi_asus_extra_models_idx holds their indices.

I have also introduced a longname attribute in both tables, which contains the full name including Manufacturer.
This is only used for correctly setting/printing driver information.


Switching WLAN on/off and reporting events to devd with various special keys and Fn-key combinations works fine.

This patch should not break anything, but I was not able to test it with a real Asus notebook.
Someone should do this before committing

>Release-Note:
>Audit-Trail:

From: Sebastian Schulze Struchtrup <sebastian@struchtrup.de>
To: Sebastian Schulze Struchtrup <seb@struchtrup.com>
Cc: FreeBSD-gnats-submit@freebsd.org, acpi@freebsd.org,
	philip@freebsd.org
Subject: Re: i386/73380: [patch] kldload acpi_asus.ko causes page fault on
 Samsung P35
Date: Mon, 01 Nov 2004 14:14:41 +0100

 This is a multi-part message in MIME format.
 --------------050207030109020209080808
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Well, the patch got lost.
 Here it is.
 
 
 
 --------------050207030109020209080808
 Content-Type: text/plain;
  name="acpi_asus.c.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="acpi_asus.c.patch"
 
 Index: acpi_asus.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/i386/acpica/acpi_asus.c,v
 retrieving revision 1.11
 diff -u -p -r1.11 acpi_asus.c
 --- acpi_asus.c	13 Aug 2004 06:22:29 -0000	1.11
 +++ acpi_asus.c	1 Nov 2004 12:48:17 -0000
 @@ -26,7 +26,7 @@
   */
  
  #include <sys/cdefs.h>
 -__FBSDID("$FreeBSD$");
 +__FBSDID("$FreeBSD: src/sys/i386/acpica/acpi_asus.c,v 1.11 2004/08/13 06:22:29 njl Exp $");
  
  /*
   * Driver for extra ACPI-controlled gadgets (hotkeys, leds, etc) found on
 @@ -58,7 +58,7 @@ ACPI_MODULE_NAME("ASUS")
  
  struct acpi_asus_model {
  	char	*name;
 -
 +	char    *longname;
  	char	*mled_set;
  	char	*tled_set;
  	char	*wled_set;
 @@ -103,9 +103,11 @@ struct acpi_asus_softc {
  };
  
  /* Models we know about */
 +/* These are identified by name returned on ATK INIT */
  static struct acpi_asus_model acpi_asus_models[] = {
  	{
  		.name		= "L2D",
 +		.longname	= "Asus L2D",
  		.mled_set	= "MLED",
  		.wled_set	= "WLED",
  		.brn_up		= "\\Q0E",
 @@ -115,6 +117,7 @@ static struct acpi_asus_model acpi_asus_
  	},
  	{
  		.name		= "L3C",
 +		.longname	= "Asus L3C",
  		.mled_set	= "MLED",
  		.wled_set	= "WLED",
  		.brn_get	= "GPLV",
 @@ -124,6 +127,7 @@ static struct acpi_asus_model acpi_asus_
  	},
  	{
  		.name		= "L3D",
 +		.longname	= "Asus L3D",
  		.mled_set	= "MLED",
  		.wled_set	= "WLED",
  		.brn_get	= "GPLV",
 @@ -133,6 +137,7 @@ static struct acpi_asus_model acpi_asus_
  	},
  	{
  		.name		= "L3H",
 +		.longname	= "Asus L3H",
  		.mled_set	= "MLED",
  		.wled_set	= "WLED",
  		.brn_get	= "GPLV",
 @@ -143,11 +148,13 @@ static struct acpi_asus_model acpi_asus_
  		.disp_set	= "SDSP"
  	},
  	{
 -		.name		= "L8L"
 +		.name		= "L8L",
 +		.longname	= "Asus L8L"
  		/* Only has hotkeys, apparantly */
  	},
  	{
  		.name		= "M1A",
 +		.longname	= "Asus M1A",
  		.mled_set	= "MLED",
  		.brn_up		= "\\_SB.PCI0.PX40.EC0.Q0E",
  		.brn_dn		= "\\_SB.PCI0.PX40.EC0.Q0F",
 @@ -156,6 +163,7 @@ static struct acpi_asus_model acpi_asus_
  	},
  	{
  		.name		= "M2E",
 +		.longname	= "Asus M2E",
  		.mled_set	= "MLED",
  		.wled_set	= "WLED",
  		.brn_get	= "GPLV",
 @@ -163,18 +171,33 @@ static struct acpi_asus_model acpi_asus_
  		.lcd_get	= "\\GP06",
  		.lcd_set	= "\\Q10"
  	},
 +
 +	{ .name = NULL }
 +};
 +
 +/* This notebook are also supported, but cannon be identified by
 + * their name because ATK INIT does not return their name
 + * update the following enum when updating this table */
 +
 +static struct acpi_asus_model acpi_asus_extra_models[] = {
  	{
  		.name		= "P30",
 +		.longname	= "Samsung P30/P35",
  		.wled_set	= "WLED",
  		.brn_up		= "\\_SB.PCI0.LPCB.EC0._Q68",
  		.brn_dn		= "\\_SB.PCI0.LPCB.EC0._Q69",
  		.lcd_get	= "\\BKLT",
  		.lcd_set	= "\\_SB.PCI0.LPCB.EC0._Q0E"
  	},
 +};
  
 -	{ .name = NULL }
 +/* must be in sync with acpi_asus_extra_models above */
 +enum acpi_asus_extra_models_idx
 +{
 +	SAMSUNG_P30 = 0	
  };
  
 +
  ACPI_SERIAL_DECL(asus, "ACPI ASUS extras");
  
  /* Function prototypes */
 @@ -218,6 +241,10 @@ acpi_asus_probe(device_t dev)
  	ACPI_BUFFER		Buf;
  	ACPI_OBJECT		Arg, *Obj;
  	ACPI_OBJECT_LIST	Args;
 +	ACPI_TABLE_HEADER dsdt_header;
 +	ACPI_STATUS	status;
 +	int has_dsdt;
 +
  	static char 		*asus_ids[] = { "ATK0100", NULL };
  
  	ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
 @@ -233,6 +260,17 @@ acpi_asus_probe(device_t dev)
  		if (sb == NULL)
  			return (ENOMEM);
  
 +		/* Get DSDT Header (copy the header into our dsdt_header struct) */
 +		status = AcpiGetTableHeader(ACPI_TABLE_DSDT, 1, &dsdt_header);
 +		if (ACPI_FAILURE(status))
 +		{
 +				device_printf(dev, "unable to load DSDT\n");
 +				has_dsdt = 0;
 +		}
 +		else
 +			has_dsdt = 1;
 +
 +		/* Call ATK INIT */
  		Arg.Type = ACPI_TYPE_INTEGER;
  		Arg.Integer.Value = 0;
  
 @@ -243,33 +281,54 @@ acpi_asus_probe(device_t dev)
  		Buf.Length = ACPI_ALLOCATE_BUFFER;
  	
  		AcpiEvaluateObject(sc->handle, "INIT", &Args, &Buf);
 -		
  		Obj = Buf.Pointer;
 -
 -		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);
 -				sbuf_finish(sb);
 -				
 -				sc->model = model;
 -				device_set_desc(dev, sbuf_data(sb));
 -
 -				sbuf_delete(sb);
 -				AcpiOsFree(Buf.Pointer);
 -				return (0);
 +		
 +		sc->model = NULL;
 +		if ((Obj != NULL) && (Obj->String.Pointer != NULL))
 +		{
 +			/* got name, loop over known models */
 +			for (model = acpi_asus_models; model->name != NULL; model++)
 +				if (strcmp(Obj->String.Pointer, model->name) == 0) {
 +					sc->model = model;
 +				}
 +
 +			if (sc->model == NULL) {
 +				sbuf_printf(sb, "Unsupported Asus laptop detected: %s\n",
 +				Obj->String.Pointer);				
 +			}
 +			AcpiOsFree(Buf.Pointer);
 +		}
 +		else
 +		{
 +			/* some notebooks don't return anything on INIT (NULL)
 +			   The Samsung P30/P35 are known to do this.
 +			*/
 +			if ((has_dsdt) && (strncmp("ODEM", dsdt_header.OemTableId, 4)==0)) {
 +				sc->model = &acpi_asus_extra_models[SAMSUNG_P30];
 +				sbuf_printf(sb, "Missing model name: "
 +								"Identified as Samsung P30/P35\n");
  			}
 +			else
 +			{
 +				sbuf_printf(sb, "Your notebook supports the asus ATK device,"
 +								" but can't be identified\n");
 +			}
 +		}
  
 -		sbuf_printf(sb, "Unsupported Asus laptop detected: %s\n",
 -				Obj->String.Pointer);
  		sbuf_finish(sb);
 -
  		device_printf(dev, sbuf_data(sb));
 -
 -		sbuf_delete(sb);
 -		AcpiOsFree(Buf.Pointer);
 +		
 +		if (sc->model != NULL)
 +		{
 +			sbuf_clear(sb);
 +			sbuf_printf(sb, "%s Laptop Extras", sc->model->longname);
 +			sbuf_finish(sb);
 +			device_set_desc(dev, sbuf_data(sb));
 +			sbuf_delete(sb);
 +			return(0);
 +		}
  	}
 -
 +	/* either not identified or disabled */
  	return (ENXIO);
  }
  
 
 --------------050207030109020209080808--
Responsible-Changed-From-To: freebsd-i386->philip 
Responsible-Changed-By: philip 
Responsible-Changed-When: Mon Nov 1 19:04:33 GMT 2004 
Responsible-Changed-Why:  
I'll take care of this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=73380 

From: Philip Paeps <philip@freebsd.org>
To: Sebastian Schulze Struchtrup <sebastian@struchtrup.de>
Cc: Sebastian Schulze Struchtrup <seb@struchtrup.com>,
	FreeBSD-gnats-submit@freebsd.org, acpi@freebsd.org
Subject: Re: i386/73380: [patch] kldload acpi_asus.ko causes page fault on Samsung P35
Date: Thu, 4 Nov 2004 12:27:57 +0100

 On 2004-11-01 14:14:41 (+0100), Sebastian Schulze Struchtrup <sebastian@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 ;-)
 
 Index: acpi_asus.c
 ===================================================================
 RCS file: /home/freebsd/FreeBSD-CVS/src/sys/i386/acpica/acpi_asus.c,v
 retrieving revision 1.12
 diff -u -r1.12 acpi_asus.c
 --- acpi_asus.c	2 Nov 2004 13:02:22 -0000	1.12
 +++ acpi_asus.c	4 Nov 2004 09:14:47 -0000
 @@ -102,7 +102,10 @@
  	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 @@
  		.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 @@
  		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 == 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 @@
  			}
  
  		sbuf_printf(sb, "Unsupported Asus laptop detected: %s\n",
 -				Obj->String.Pointer);
 +		    Obj->String.Pointer);
  		sbuf_finish(sb);
  
  		device_printf(dev, sbuf_data(sb));
 
  - Philip
 
 -- 
 Philip Paeps                                  Made from non-edible parts
 philip@freebsd.org
 
   BOFH Excuse #228:
     That function is not currently supported, but Bill Gates assures us it
     will be featured in the next upgrade.
State-Changed-From-To: open->feedback 
State-Changed-By: philip 
State-Changed-When: Thu Nov 4 11:41:23 GMT 2004 
State-Changed-Why:  


http://www.freebsd.org/cgi/query-pr.cgi?pr=73380 

From: Sebastian Schulze Struchtrup <sebastian@struchtrup.de>
To: Philip Paeps <philip@freebsd.org>
Cc: Sebastian Schulze Struchtrup <seb@struchtrup.com>,
	FreeBSD-gnats-submit@freebsd.org, acpi@freebsd.org
Subject: Re: i386/73380: [patch] kldload acpi_asus.ko causes page fault on
 Samsung P35
Date: Thu, 04 Nov 2004 14:18:44 +0100

 This is a multi-part message in MIME format.
 --------------020603070606090906090205
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Philip Paeps wrote:
 
 >On 2004-11-01 14:14:41 (+0100), Sebastian Schulze Struchtrup <sebastian@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.
 
 
 --------------020603070606090906090205
 Content-Type: text/plain;
  name="acpi_asus.c.patch-2"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="acpi_asus.c.patch-2"
 
 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));
 
 --------------020603070606090906090205--
State-Changed-From-To: feedback->closed 
State-Changed-By: philip 
State-Changed-When: Fri Nov 5 07:24:54 GMT 2004 
State-Changed-Why:  
Committed, thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=73380 
>Unformatted:
