All of lore.kernel.org
 help / color / mirror / Atom feed
* asus_atk0110 not working on Asus P7P55D PRO
@ 2009-09-17  5:28 Robert Hancock
  2009-09-17  9:17   ` Luca Tettamanti
  2009-09-20 16:23 ` Luca Tettamanti
  0 siblings, 2 replies; 14+ messages in thread
From: Robert Hancock @ 2009-09-17  5:28 UTC (permalink / raw)
  To: linux-kernel, linux-acpi; +Cc: Luca Tettamanti

[-- Attachment #1: Type: text/plain, Size: 882 bytes --]

Just built a new system with an Asus P7P55D PRO motherboard. The ATK0110 
driver doesn't seem to be able to retrieve any hardware monitoring 
parameters successfully, sensors gives:

atk0110-acpi-0
Adapter: ACPI interface
ERROR: Can't get value of subfeature in0_input: I/O error
Vcore Voltage:      +0.00 V  (min =  +0.80 V, max =  +1.60 V)
ERROR: Can't get value of subfeature in1_input: I/O error
+3.3V Voltage:      +0.00 V  (min =  +2.97 V, max =  +3.63 V)
ERROR: Can't get value of subfeature in2_input: I/O error
+5V Voltage:        +0.00 V  (min =  +4.50 V, max =  +5.50 V)

etc. and dmesg spits out a bunch of these:

ATK0110 ATK0110:00: atk_read_value_new: ACPI exception: AE_BUFFER_OVERFLOW

I'm guessing this board uses a different format than what the driver is 
expecting. I'm attaching the gzipped decompiled DSDT from the board, 
hopefully it's useful to somebody..

[-- Attachment #2: p7p55dpro.asl.gz --]
[-- Type: application/x-gzip, Size: 41457 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
  2009-09-17  5:28 asus_atk0110 not working on Asus P7P55D PRO Robert Hancock
@ 2009-09-17  9:17   ` Luca Tettamanti
  2009-09-20 16:23 ` Luca Tettamanti
  1 sibling, 0 replies; 14+ messages in thread
From: Luca Tettamanti @ 2009-09-17  9:17 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel, linux-acpi

On Thu, Sep 17, 2009 at 7:28 AM, Robert Hancock <hancockrwd@gmail.com> wrote:
> Just built a new system with an Asus P7P55D PRO motherboard. The ATK0110
> driver doesn't seem to be able to retrieve any hardware monitoring
> parameters successfully, sensors gives:
>
> atk0110-acpi-0
> Adapter: ACPI interface
> ERROR: Can't get value of subfeature in0_input: I/O error
> Vcore Voltage:      +0.00 V  (min =  +0.80 V, max =  +1.60 V)
> ERROR: Can't get value of subfeature in1_input: I/O error
> +3.3V Voltage:      +0.00 V  (min =  +2.97 V, max =  +3.63 V)
> ERROR: Can't get value of subfeature in2_input: I/O error
> +5V Voltage:        +0.00 V  (min =  +4.50 V, max =  +5.50 V)
>
> etc. and dmesg spits out a bunch of these:
>
> ATK0110 ATK0110:00: atk_read_value_new: ACPI exception: AE_BUFFER_OVERFLOW

Hum, they changed the output buffer size. I'm working on a fix.

Luca
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
@ 2009-09-17  9:17   ` Luca Tettamanti
  0 siblings, 0 replies; 14+ messages in thread
From: Luca Tettamanti @ 2009-09-17  9:17 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel, linux-acpi

On Thu, Sep 17, 2009 at 7:28 AM, Robert Hancock <hancockrwd@gmail.com> wrote:
> Just built a new system with an Asus P7P55D PRO motherboard. The ATK0110
> driver doesn't seem to be able to retrieve any hardware monitoring
> parameters successfully, sensors gives:
>
> atk0110-acpi-0
> Adapter: ACPI interface
> ERROR: Can't get value of subfeature in0_input: I/O error
> Vcore Voltage:      +0.00 V  (min =  +0.80 V, max =  +1.60 V)
> ERROR: Can't get value of subfeature in1_input: I/O error
> +3.3V Voltage:      +0.00 V  (min =  +2.97 V, max =  +3.63 V)
> ERROR: Can't get value of subfeature in2_input: I/O error
> +5V Voltage:        +0.00 V  (min =  +4.50 V, max =  +5.50 V)
>
> etc. and dmesg spits out a bunch of these:
>
> ATK0110 ATK0110:00: atk_read_value_new: ACPI exception: AE_BUFFER_OVERFLOW

Hum, they changed the output buffer size. I'm working on a fix.

Luca

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
  2009-09-17  5:28 asus_atk0110 not working on Asus P7P55D PRO Robert Hancock
  2009-09-17  9:17   ` Luca Tettamanti
@ 2009-09-20 16:23 ` Luca Tettamanti
  2009-09-20 17:47     ` Robert Hancock
  1 sibling, 1 reply; 14+ messages in thread
From: Luca Tettamanti @ 2009-09-20 16:23 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel, linux-acpi

Il Wed, Sep 16, 2009 at 11:28:39PM -0600, Robert Hancock ha scritto: 
> Just built a new system with an Asus P7P55D PRO motherboard. The
> ATK0110 driver doesn't seem to be able to retrieve any hardware
> monitoring parameters successfully, sensors gives:
> 
> atk0110-acpi-0
> Adapter: ACPI interface
> ERROR: Can't get value of subfeature in0_input: I/O error
> Vcore Voltage:      +0.00 V  (min =  +0.80 V, max =  +1.60 V)
> ERROR: Can't get value of subfeature in1_input: I/O error
> +3.3V Voltage:      +0.00 V  (min =  +2.97 V, max =  +3.63 V)
> ERROR: Can't get value of subfeature in2_input: I/O error
> +5V Voltage:        +0.00 V  (min =  +4.50 V, max =  +5.50 V)
> 
> etc. and dmesg spits out a bunch of these:
> 
> ATK0110 ATK0110:00: atk_read_value_new: ACPI exception: AE_BUFFER_OVERFLOW
> 
> I'm guessing this board uses a different format than what the driver
> is expecting. I'm attaching the gzipped decompiled DSDT from the
> board, hopefully it's useful to somebody..

Please try the following patch, it should detect the proper buffer size.

diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index fe4fa29..4f6f5ec 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -75,6 +75,13 @@ enum atk_pack_member {
 #define _HWMON_OLD_PACK_ENABLE	4
 
 
+struct atk_acpi_out_buffer {
+	union acpi_object buf;
+	u32 flags;
+	u32 value;
+	u8 data[];
+};
+
 struct atk_data {
 	struct device *hwmon_dev;
 	acpi_handle atk_handle;
@@ -94,6 +101,10 @@ struct atk_data {
 	int temperature_count;
 	int fan_count;
 	struct list_head sensor_list;
+	
+	struct atk_acpi_out_buffer *buffer;
+	size_t buffer_size;
+	struct mutex buffer_lock;
 };
 
 
@@ -129,11 +140,6 @@ struct atk_sensor_data {
 	char const *acpi_name;
 };
 
-struct atk_acpi_buffer_u64 {
-	union acpi_object buf;
-	u64 value;
-};
-
 static int atk_add(struct acpi_device *device);
 static int atk_remove(struct acpi_device *device, int type);
 static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
@@ -446,8 +452,9 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	struct acpi_object_list params;
 	struct acpi_buffer ret;
 	union acpi_object id;
-	struct atk_acpi_buffer_u64 tmp;
+	union acpi_object buf;
 	acpi_status status;
+	int err = 0;
 
 	id.type = ACPI_TYPE_INTEGER;
 	id.integer.value = sensor->id;
@@ -455,36 +462,35 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	params.count = 1;
 	params.pointer = &id;
 
-	tmp.buf.type = ACPI_TYPE_BUFFER;
-	tmp.buf.buffer.pointer = (u8 *)&tmp.value;
-	tmp.buf.buffer.length = sizeof(u64);
-	ret.length = sizeof(tmp);
-	ret.pointer = &tmp;
+	mutex_lock(&data->buffer_lock);
+
+	ret.length = data->buffer_size;
+	ret.pointer = &buf;
 
 	status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
 			&ret, ACPI_TYPE_BUFFER);
 	if (status != AE_OK) {
 		dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
 				acpi_format_exception(status));
-		return -EIO;
+		err = -EIO;
+		goto out;
 	}
 
-	/* Return buffer format:
-	 * [0-3] "value" is valid flag
-	 * [4-7] value
-	 */
-	if (!(tmp.value & 0xffffffff)) {
+	if (!data->buffer->flags) {
 		/* The reading is not valid, possible causes:
 		 * - sensor failure
 		 * - enumeration was FUBAR (and we didn't notice)
 		 */
-		dev_info(dev, "Failure: %#llx\n", tmp.value);
-		return -EIO;
+		dev_info(dev, "Failure: %#x\n", data->buffer->flags);
+	
+		err = -EIO;
+		goto out;
 	}
 
-	*value = (tmp.value & 0xffffffff00000000ULL) >> 32;
-
-	return 0;
+	*value = data->buffer->value;
+out:
+	mutex_unlock(&data->buffer_lock);
+	return err;
 }
 
 static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
@@ -721,11 +727,40 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	struct acpi_object_list params;
 	union acpi_object id;
 	union acpi_object *pack;
+	union acpi_object *asbf;
 	int err;
 	int i;
 
 	dev_dbg(dev, "Enumerating hwmon sensors\n");
 
+	/* Probe ASBF */
+	buf.length = ACPI_ALLOCATE_BUFFER;
+	ret = acpi_evaluate_object_typed(data->atk_handle, "ASBF", NULL, &buf,
+			ACPI_TYPE_BUFFER);
+	if (ret != AE_OK) {
+		dev_warn(dev, "Failed to evaluate ASBF: %s\n",
+				acpi_format_exception(ret));
+		return -ENODEV;
+	}
+	asbf = buf.pointer;
+	data->buffer_size = asbf->buffer.length;
+	ACPI_FREE(buf.pointer);
+	buf.pointer = NULL;
+	
+	dev_dbg(dev, "ASBF buffer size: %zu\n", data->buffer_size);
+	/* Sanity check */
+	if (data->buffer_size < 8 || data->buffer_size > 512) {
+		dev_warn(dev, "Invalid ASBF buffer size: %zu\n",
+				data->buffer_size);
+		return -EINVAL;
+	}
+	data->buffer_size += sizeof(union acpi_object);
+
+	data->buffer = kzalloc(data->buffer_size, GFP_KERNEL);
+	if (!data->buffer)
+		return -ENOMEM;
+	mutex_init(&data->buffer_lock);
+
 	id.type = ACPI_TYPE_INTEGER;
 	id.integer.value = ATK_MUX_HWMON;
 	params.count = 1;
@@ -737,7 +772,8 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	if (ret != AE_OK) {
 		dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n",
 				acpi_format_exception(ret));
-		return -ENODEV;
+		err = -ENODEV;
+		goto out;
 	}
 
 	/* Result must be a package */
@@ -759,6 +795,8 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	err = data->voltage_count + data->temperature_count + data->fan_count;
 
 out:
+	if (err < 0)
+		kfree(data->buffer);
 	ACPI_FREE(buf.pointer);
 	return err;
 }
@@ -988,6 +1026,7 @@ static int atk_remove(struct acpi_device *device, int type)
 	atk_free_sensors(data);
 	hwmon_device_unregister(data->hwmon_dev);
 
+	kfree(data->buffer);
 	kfree(data);
 
 	return 0;

Luca
-- 
"La vita potrebbe non avere alcun significato. Oppure, ancora peggio,
 potrebbe averne uno che disapprovo". -- Ashleigh Brilliant

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
  2009-09-20 16:23 ` Luca Tettamanti
@ 2009-09-20 17:47     ` Robert Hancock
  0 siblings, 0 replies; 14+ messages in thread
From: Robert Hancock @ 2009-09-20 17:47 UTC (permalink / raw)
  To: Luca Tettamanti; +Cc: linux-kernel, linux-acpi

On Sun, Sep 20, 2009 at 10:23 AM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> Il Wed, Sep 16, 2009 at 11:28:39PM -0600, Robert Hancock ha scritto:
>> Just built a new system with an Asus P7P55D PRO motherboard. The
>> ATK0110 driver doesn't seem to be able to retrieve any hardware
>> monitoring parameters successfully, sensors gives:
>>
>> atk0110-acpi-0
>> Adapter: ACPI interface
>> ERROR: Can't get value of subfeature in0_input: I/O error
>> Vcore Voltage:      +0.00 V  (min =  +0.80 V, max =  +1.60 V)
>> ERROR: Can't get value of subfeature in1_input: I/O error
>> +3.3V Voltage:      +0.00 V  (min =  +2.97 V, max =  +3.63 V)
>> ERROR: Can't get value of subfeature in2_input: I/O error
>> +5V Voltage:        +0.00 V  (min =  +4.50 V, max =  +5.50 V)
>>
>> etc. and dmesg spits out a bunch of these:
>>
>> ATK0110 ATK0110:00: atk_read_value_new: ACPI exception: AE_BUFFER_OVERFLOW
>>
>> I'm guessing this board uses a different format than what the driver
>> is expecting. I'm attaching the gzipped decompiled DSDT from the
>> board, hopefully it's useful to somebody..
>
> Please try the following patch, it should detect the proper buffer size.
>

Obviously something not quite right:

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffff81301b1f>] acpi_ut_copy_isimple_to_esimple+0x3e/0x16e
PGD 11d5c8067 PUD 11d680067 PMD 0
Oops: 0002 [#1] SMP
last sysfs file:
/sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03/ATK0110:00/hwmon/hwmon0/in0_input
CPU 3
Modules linked in: ipv6 cpufreq_ondemand acpi_cpufreq freq_table fuse
dm_multipath uinput snd_ice1724 snd_rawmidi snd_seq_device
snd_hda_codec_via snd_ice17xx_ak4xxx snd_ac97_codec snd_hda_intel
snd_hda_codec ac97_bus snd_ak4xxx_adda snd_ak4114 snd_hwdep snd_pcm
snd_pt2258 snd_i2c snd_timer gspca_spca561 snd gspca_main videodev
ata_generic r8169 v4l1_compat firewire_ohci pata_acpi usb_storage
firewire_core i2c_i801 snd_page_alloc soundcore mii
v4l2_compat_ioctl32 asus_atk0110 wmi joydev pata_jmicron i2c_core
pcspkr serio_raw hwmon crc_itu_t [last unloaded: scsi_wait_scan]
Pid: 2475, comm: sensors-applet Not tainted 2.6.31-rc0 #6 System Product Name
RIP: 0010:[<ffffffff81301b1f>]  [<ffffffff81301b1f>]
acpi_ut_copy_isimple_to_esimple+0x3e/0x16e
RSP: 0018:ffff88011f2d1c48  EFLAGS: 00010282
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006
RDX: 0000000000000018 RSI: ffff88011f2d1dc8 RDI: 0000000000000000
RBP: ffff88011f2d1c68 R08: ffff88013ba9a2d0 R09: ffff88013ba9a2d0
R10: 00000000c261101f R11: 00000000c261101f R12: ffff88013ba70a40
R13: ffff88011f2d1dd8 R14: ffff88013b2d3fc0 R15: ffff88011f2d1dc8
FS:  00007f7cdbea1800(0000) GS:ffff880028260000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 000000011f398000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process sensors-applet (pid: 2475, threadinfo ffff88011f2d0000, task
ffff88011f2c8000)
Stack:
 0000000000004001 00000000c261101f ffff88011f2d1cc8 ffff88011f2d1dc8
<0> ffff88011f2d1ca8 ffffffff81301ce3 ffff88013b2d3fc0 00000000c261101f
<0> 0000000000000000 00000000c261101f 0000000000000000 0000000000000000
Call Trace:
 [<ffffffff81301ce3>] acpi_ut_copy_iobject_to_eobject+0x94/0xb3
 [<ffffffff812f6911>] acpi_evaluate_object+0x1b5/0x21a
 [<ffffffff812f69b1>] acpi_evaluate_object_typed+0x3b/0xfa
 [<ffffffffa00405d6>] atk_input_show+0x1a0/0x2bb [asus_atk0110]
 [<ffffffff81011f82>] ? system_call_fastpath+0x16/0x1b
Code: 28 00 00 00 48 89 45 e8 31 c0 48 89 f3 49 89 f8 48 89 ce 48 c7
01 00 00 00 00 48 85 ff 0f 84 1d 01 00 00 b9 06 00 00 00 48 89 df <f3>
ab 41 0f b6 40 09 89 03 41 8a 78 09 40 80 ff 03 74 56 77 12
RIP  [<ffffffff81301b1f>] acpi_ut_copy_isimple_to_esimple+0x3e/0x16e
 RSP <ffff88011f2d1c48>
CR2: 0000000000000000
---[ end trace d7191dbc499ceceb ]---

Based on the disassembly I think this memset is what failed in
drivers/acpi/acpica/utcopy.c, in the acpi_ut_copy_isimple_to_esimple
function:

	/* Always clear the external object */

	ACPI_MEMSET(external_object, 0, sizeof(union acpi_object));
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
@ 2009-09-20 17:47     ` Robert Hancock
  0 siblings, 0 replies; 14+ messages in thread
From: Robert Hancock @ 2009-09-20 17:47 UTC (permalink / raw)
  To: Luca Tettamanti; +Cc: linux-kernel, linux-acpi

On Sun, Sep 20, 2009 at 10:23 AM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> Il Wed, Sep 16, 2009 at 11:28:39PM -0600, Robert Hancock ha scritto:
>> Just built a new system with an Asus P7P55D PRO motherboard. The
>> ATK0110 driver doesn't seem to be able to retrieve any hardware
>> monitoring parameters successfully, sensors gives:
>>
>> atk0110-acpi-0
>> Adapter: ACPI interface
>> ERROR: Can't get value of subfeature in0_input: I/O error
>> Vcore Voltage:      +0.00 V  (min =  +0.80 V, max =  +1.60 V)
>> ERROR: Can't get value of subfeature in1_input: I/O error
>> +3.3V Voltage:      +0.00 V  (min =  +2.97 V, max =  +3.63 V)
>> ERROR: Can't get value of subfeature in2_input: I/O error
>> +5V Voltage:        +0.00 V  (min =  +4.50 V, max =  +5.50 V)
>>
>> etc. and dmesg spits out a bunch of these:
>>
>> ATK0110 ATK0110:00: atk_read_value_new: ACPI exception: AE_BUFFER_OVERFLOW
>>
>> I'm guessing this board uses a different format than what the driver
>> is expecting. I'm attaching the gzipped decompiled DSDT from the
>> board, hopefully it's useful to somebody..
>
> Please try the following patch, it should detect the proper buffer size.
>

Obviously something not quite right:

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffff81301b1f>] acpi_ut_copy_isimple_to_esimple+0x3e/0x16e
PGD 11d5c8067 PUD 11d680067 PMD 0
Oops: 0002 [#1] SMP
last sysfs file:
/sys/devices/LNXSYSTM:00/device:00/PNP0A08:00/device:03/ATK0110:00/hwmon/hwmon0/in0_input
CPU 3
Modules linked in: ipv6 cpufreq_ondemand acpi_cpufreq freq_table fuse
dm_multipath uinput snd_ice1724 snd_rawmidi snd_seq_device
snd_hda_codec_via snd_ice17xx_ak4xxx snd_ac97_codec snd_hda_intel
snd_hda_codec ac97_bus snd_ak4xxx_adda snd_ak4114 snd_hwdep snd_pcm
snd_pt2258 snd_i2c snd_timer gspca_spca561 snd gspca_main videodev
ata_generic r8169 v4l1_compat firewire_ohci pata_acpi usb_storage
firewire_core i2c_i801 snd_page_alloc soundcore mii
v4l2_compat_ioctl32 asus_atk0110 wmi joydev pata_jmicron i2c_core
pcspkr serio_raw hwmon crc_itu_t [last unloaded: scsi_wait_scan]
Pid: 2475, comm: sensors-applet Not tainted 2.6.31-rc0 #6 System Product Name
RIP: 0010:[<ffffffff81301b1f>]  [<ffffffff81301b1f>]
acpi_ut_copy_isimple_to_esimple+0x3e/0x16e
RSP: 0018:ffff88011f2d1c48  EFLAGS: 00010282
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006
RDX: 0000000000000018 RSI: ffff88011f2d1dc8 RDI: 0000000000000000
RBP: ffff88011f2d1c68 R08: ffff88013ba9a2d0 R09: ffff88013ba9a2d0
R10: 00000000c261101f R11: 00000000c261101f R12: ffff88013ba70a40
R13: ffff88011f2d1dd8 R14: ffff88013b2d3fc0 R15: ffff88011f2d1dc8
FS:  00007f7cdbea1800(0000) GS:ffff880028260000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 000000011f398000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process sensors-applet (pid: 2475, threadinfo ffff88011f2d0000, task
ffff88011f2c8000)
Stack:
 0000000000004001 00000000c261101f ffff88011f2d1cc8 ffff88011f2d1dc8
<0> ffff88011f2d1ca8 ffffffff81301ce3 ffff88013b2d3fc0 00000000c261101f
<0> 0000000000000000 00000000c261101f 0000000000000000 0000000000000000
Call Trace:
 [<ffffffff81301ce3>] acpi_ut_copy_iobject_to_eobject+0x94/0xb3
 [<ffffffff812f6911>] acpi_evaluate_object+0x1b5/0x21a
 [<ffffffff812f69b1>] acpi_evaluate_object_typed+0x3b/0xfa
 [<ffffffffa00405d6>] atk_input_show+0x1a0/0x2bb [asus_atk0110]
 [<ffffffff81011f82>] ? system_call_fastpath+0x16/0x1b
Code: 28 00 00 00 48 89 45 e8 31 c0 48 89 f3 49 89 f8 48 89 ce 48 c7
01 00 00 00 00 48 85 ff 0f 84 1d 01 00 00 b9 06 00 00 00 48 89 df <f3>
ab 41 0f b6 40 09 89 03 41 8a 78 09 40 80 ff 03 74 56 77 12
RIP  [<ffffffff81301b1f>] acpi_ut_copy_isimple_to_esimple+0x3e/0x16e
 RSP <ffff88011f2d1c48>
CR2: 0000000000000000
---[ end trace d7191dbc499ceceb ]---

Based on the disassembly I think this memset is what failed in
drivers/acpi/acpica/utcopy.c, in the acpi_ut_copy_isimple_to_esimple
function:

	/* Always clear the external object */

	ACPI_MEMSET(external_object, 0, sizeof(union acpi_object));

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
  2009-09-20 17:47     ` Robert Hancock
@ 2009-09-20 18:58       ` Luca Tettamanti
  -1 siblings, 0 replies; 14+ messages in thread
From: Luca Tettamanti @ 2009-09-20 18:58 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel, linux-acpi

Il Sun, Sep 20, 2009 at 11:47:25AM -0600, Robert Hancock ha scritto: 
> On Sun, Sep 20, 2009 at 10:23 AM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> > Il Wed, Sep 16, 2009 at 11:28:39PM -0600, Robert Hancock ha scritto:
> >> Just built a new system with an Asus P7P55D PRO motherboard. The
> >> ATK0110 driver doesn't seem to be able to retrieve any hardware
> >> monitoring parameters successfully, sensors gives:
> >>
> >> atk0110-acpi-0
> >> Adapter: ACPI interface
> >> ERROR: Can't get value of subfeature in0_input: I/O error
> >> Vcore Voltage:      +0.00 V  (min =  +0.80 V, max =  +1.60 V)
> >> ERROR: Can't get value of subfeature in1_input: I/O error
> >> +3.3V Voltage:      +0.00 V  (min =  +2.97 V, max =  +3.63 V)
> >> ERROR: Can't get value of subfeature in2_input: I/O error
> >> +5V Voltage:        +0.00 V  (min =  +4.50 V, max =  +5.50 V)
> >>
> >> etc. and dmesg spits out a bunch of these:
> >>
> >> ATK0110 ATK0110:00: atk_read_value_new: ACPI exception: AE_BUFFER_OVERFLOW
> >>
> >> I'm guessing this board uses a different format than what the driver
> >> is expecting. I'm attaching the gzipped decompiled DSDT from the
> >> board, hopefully it's useful to somebody..
> >
> > Please try the following patch, it should detect the proper buffer size.
> >
> 
> Obviously something not quite right:

Ah yes, the pointer for the output buffer was pointing to the wrong
variable. Sorry for that ;)


diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index fe4fa29..f1056cf 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -75,6 +75,13 @@ enum atk_pack_member {
 #define _HWMON_OLD_PACK_ENABLE	4
 
 
+struct atk_acpi_out_buffer {
+	union acpi_object buf;
+	u32 flags;
+	u32 value;
+	u8 data[];
+};
+
 struct atk_data {
 	struct device *hwmon_dev;
 	acpi_handle atk_handle;
@@ -94,6 +101,10 @@ struct atk_data {
 	int temperature_count;
 	int fan_count;
 	struct list_head sensor_list;
+
+	struct atk_acpi_out_buffer *buffer;
+	size_t buffer_size;
+	struct mutex buffer_lock;
 };
 
 
@@ -129,11 +140,6 @@ struct atk_sensor_data {
 	char const *acpi_name;
 };
 
-struct atk_acpi_buffer_u64 {
-	union acpi_object buf;
-	u64 value;
-};
-
 static int atk_add(struct acpi_device *device);
 static int atk_remove(struct acpi_device *device, int type);
 static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
@@ -446,8 +452,8 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	struct acpi_object_list params;
 	struct acpi_buffer ret;
 	union acpi_object id;
-	struct atk_acpi_buffer_u64 tmp;
 	acpi_status status;
+	int err = 0;
 
 	id.type = ACPI_TYPE_INTEGER;
 	id.integer.value = sensor->id;
@@ -455,36 +461,35 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	params.count = 1;
 	params.pointer = &id;
 
-	tmp.buf.type = ACPI_TYPE_BUFFER;
-	tmp.buf.buffer.pointer = (u8 *)&tmp.value;
-	tmp.buf.buffer.length = sizeof(u64);
-	ret.length = sizeof(tmp);
-	ret.pointer = &tmp;
+	mutex_lock(&data->buffer_lock);
+
+	ret.length = data->buffer_size;
+	ret.pointer = data->buffer;
 
 	status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
 			&ret, ACPI_TYPE_BUFFER);
 	if (status != AE_OK) {
 		dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
 				acpi_format_exception(status));
-		return -EIO;
+		err = -EIO;
+		goto out;
 	}
 
-	/* Return buffer format:
-	 * [0-3] "value" is valid flag
-	 * [4-7] value
-	 */
-	if (!(tmp.value & 0xffffffff)) {
+	if (!data->buffer->flags) {
 		/* The reading is not valid, possible causes:
 		 * - sensor failure
 		 * - enumeration was FUBAR (and we didn't notice)
 		 */
-		dev_info(dev, "Failure: %#llx\n", tmp.value);
-		return -EIO;
-	}
+		dev_info(dev, "Failure: %#x\n", data->buffer->flags);
 
-	*value = (tmp.value & 0xffffffff00000000ULL) >> 32;
+		err = -EIO;
+		goto out;
+	}
 
-	return 0;
+	*value = data->buffer->value;
+out:
+	mutex_unlock(&data->buffer_lock);
+	return err;
 }
 
 static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
@@ -721,11 +726,40 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	struct acpi_object_list params;
 	union acpi_object id;
 	union acpi_object *pack;
+	union acpi_object *asbf;
 	int err;
 	int i;
 
 	dev_dbg(dev, "Enumerating hwmon sensors\n");
 
+	/* Probe ASBF */
+	buf.length = ACPI_ALLOCATE_BUFFER;
+	ret = acpi_evaluate_object_typed(data->atk_handle, "ASBF", NULL, &buf,
+			ACPI_TYPE_BUFFER);
+	if (ret != AE_OK) {
+		dev_warn(dev, "Failed to evaluate ASBF: %s\n",
+				acpi_format_exception(ret));
+		return -ENODEV;
+	}
+	asbf = buf.pointer;
+	data->buffer_size = asbf->buffer.length;
+	ACPI_FREE(buf.pointer);
+	buf.pointer = NULL;
+
+	dev_dbg(dev, "ASBF buffer size: %zu\n", data->buffer_size);
+	/* Sanity check */
+	if (data->buffer_size < 8 || data->buffer_size > 512) {
+		dev_warn(dev, "Invalid ASBF buffer size: %zu\n",
+				data->buffer_size);
+		return -EINVAL;
+	}
+	data->buffer_size += sizeof(union acpi_object);
+
+	data->buffer = kzalloc(data->buffer_size, GFP_KERNEL);
+	if (!data->buffer)
+		return -ENOMEM;
+	mutex_init(&data->buffer_lock);
+
 	id.type = ACPI_TYPE_INTEGER;
 	id.integer.value = ATK_MUX_HWMON;
 	params.count = 1;
@@ -737,7 +771,8 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	if (ret != AE_OK) {
 		dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n",
 				acpi_format_exception(ret));
-		return -ENODEV;
+		err = -ENODEV;
+		goto out;
 	}
 
 	/* Result must be a package */
@@ -759,6 +794,8 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	err = data->voltage_count + data->temperature_count + data->fan_count;
 
 out:
+	if (err < 0)
+		kfree(data->buffer);
 	ACPI_FREE(buf.pointer);
 	return err;
 }
@@ -988,6 +1025,7 @@ static int atk_remove(struct acpi_device *device, int type)
 	atk_free_sensors(data);
 	hwmon_device_unregister(data->hwmon_dev);
 
+	kfree(data->buffer);
 	kfree(data);
 
 	return 0;


Luca
-- 
The trouble with computers is that they do what you tell them, 
not what you want.
D. Cohen
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
@ 2009-09-20 18:58       ` Luca Tettamanti
  0 siblings, 0 replies; 14+ messages in thread
From: Luca Tettamanti @ 2009-09-20 18:58 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel, linux-acpi

Il Sun, Sep 20, 2009 at 11:47:25AM -0600, Robert Hancock ha scritto: 
> On Sun, Sep 20, 2009 at 10:23 AM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> > Il Wed, Sep 16, 2009 at 11:28:39PM -0600, Robert Hancock ha scritto:
> >> Just built a new system with an Asus P7P55D PRO motherboard. The
> >> ATK0110 driver doesn't seem to be able to retrieve any hardware
> >> monitoring parameters successfully, sensors gives:
> >>
> >> atk0110-acpi-0
> >> Adapter: ACPI interface
> >> ERROR: Can't get value of subfeature in0_input: I/O error
> >> Vcore Voltage:      +0.00 V  (min =  +0.80 V, max =  +1.60 V)
> >> ERROR: Can't get value of subfeature in1_input: I/O error
> >> +3.3V Voltage:      +0.00 V  (min =  +2.97 V, max =  +3.63 V)
> >> ERROR: Can't get value of subfeature in2_input: I/O error
> >> +5V Voltage:        +0.00 V  (min =  +4.50 V, max =  +5.50 V)
> >>
> >> etc. and dmesg spits out a bunch of these:
> >>
> >> ATK0110 ATK0110:00: atk_read_value_new: ACPI exception: AE_BUFFER_OVERFLOW
> >>
> >> I'm guessing this board uses a different format than what the driver
> >> is expecting. I'm attaching the gzipped decompiled DSDT from the
> >> board, hopefully it's useful to somebody..
> >
> > Please try the following patch, it should detect the proper buffer size.
> >
> 
> Obviously something not quite right:

Ah yes, the pointer for the output buffer was pointing to the wrong
variable. Sorry for that ;)


diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index fe4fa29..f1056cf 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -75,6 +75,13 @@ enum atk_pack_member {
 #define _HWMON_OLD_PACK_ENABLE	4
 
 
+struct atk_acpi_out_buffer {
+	union acpi_object buf;
+	u32 flags;
+	u32 value;
+	u8 data[];
+};
+
 struct atk_data {
 	struct device *hwmon_dev;
 	acpi_handle atk_handle;
@@ -94,6 +101,10 @@ struct atk_data {
 	int temperature_count;
 	int fan_count;
 	struct list_head sensor_list;
+
+	struct atk_acpi_out_buffer *buffer;
+	size_t buffer_size;
+	struct mutex buffer_lock;
 };
 
 
@@ -129,11 +140,6 @@ struct atk_sensor_data {
 	char const *acpi_name;
 };
 
-struct atk_acpi_buffer_u64 {
-	union acpi_object buf;
-	u64 value;
-};
-
 static int atk_add(struct acpi_device *device);
 static int atk_remove(struct acpi_device *device, int type);
 static void atk_print_sensor(struct atk_data *data, union acpi_object *obj);
@@ -446,8 +452,8 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	struct acpi_object_list params;
 	struct acpi_buffer ret;
 	union acpi_object id;
-	struct atk_acpi_buffer_u64 tmp;
 	acpi_status status;
+	int err = 0;
 
 	id.type = ACPI_TYPE_INTEGER;
 	id.integer.value = sensor->id;
@@ -455,36 +461,35 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	params.count = 1;
 	params.pointer = &id;
 
-	tmp.buf.type = ACPI_TYPE_BUFFER;
-	tmp.buf.buffer.pointer = (u8 *)&tmp.value;
-	tmp.buf.buffer.length = sizeof(u64);
-	ret.length = sizeof(tmp);
-	ret.pointer = &tmp;
+	mutex_lock(&data->buffer_lock);
+
+	ret.length = data->buffer_size;
+	ret.pointer = data->buffer;
 
 	status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
 			&ret, ACPI_TYPE_BUFFER);
 	if (status != AE_OK) {
 		dev_warn(dev, "%s: ACPI exception: %s\n", __func__,
 				acpi_format_exception(status));
-		return -EIO;
+		err = -EIO;
+		goto out;
 	}
 
-	/* Return buffer format:
-	 * [0-3] "value" is valid flag
-	 * [4-7] value
-	 */
-	if (!(tmp.value & 0xffffffff)) {
+	if (!data->buffer->flags) {
 		/* The reading is not valid, possible causes:
 		 * - sensor failure
 		 * - enumeration was FUBAR (and we didn't notice)
 		 */
-		dev_info(dev, "Failure: %#llx\n", tmp.value);
-		return -EIO;
-	}
+		dev_info(dev, "Failure: %#x\n", data->buffer->flags);
 
-	*value = (tmp.value & 0xffffffff00000000ULL) >> 32;
+		err = -EIO;
+		goto out;
+	}
 
-	return 0;
+	*value = data->buffer->value;
+out:
+	mutex_unlock(&data->buffer_lock);
+	return err;
 }
 
 static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
@@ -721,11 +726,40 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	struct acpi_object_list params;
 	union acpi_object id;
 	union acpi_object *pack;
+	union acpi_object *asbf;
 	int err;
 	int i;
 
 	dev_dbg(dev, "Enumerating hwmon sensors\n");
 
+	/* Probe ASBF */
+	buf.length = ACPI_ALLOCATE_BUFFER;
+	ret = acpi_evaluate_object_typed(data->atk_handle, "ASBF", NULL, &buf,
+			ACPI_TYPE_BUFFER);
+	if (ret != AE_OK) {
+		dev_warn(dev, "Failed to evaluate ASBF: %s\n",
+				acpi_format_exception(ret));
+		return -ENODEV;
+	}
+	asbf = buf.pointer;
+	data->buffer_size = asbf->buffer.length;
+	ACPI_FREE(buf.pointer);
+	buf.pointer = NULL;
+
+	dev_dbg(dev, "ASBF buffer size: %zu\n", data->buffer_size);
+	/* Sanity check */
+	if (data->buffer_size < 8 || data->buffer_size > 512) {
+		dev_warn(dev, "Invalid ASBF buffer size: %zu\n",
+				data->buffer_size);
+		return -EINVAL;
+	}
+	data->buffer_size += sizeof(union acpi_object);
+
+	data->buffer = kzalloc(data->buffer_size, GFP_KERNEL);
+	if (!data->buffer)
+		return -ENOMEM;
+	mutex_init(&data->buffer_lock);
+
 	id.type = ACPI_TYPE_INTEGER;
 	id.integer.value = ATK_MUX_HWMON;
 	params.count = 1;
@@ -737,7 +771,8 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	if (ret != AE_OK) {
 		dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n",
 				acpi_format_exception(ret));
-		return -ENODEV;
+		err = -ENODEV;
+		goto out;
 	}
 
 	/* Result must be a package */
@@ -759,6 +794,8 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
 	err = data->voltage_count + data->temperature_count + data->fan_count;
 
 out:
+	if (err < 0)
+		kfree(data->buffer);
 	ACPI_FREE(buf.pointer);
 	return err;
 }
@@ -988,6 +1025,7 @@ static int atk_remove(struct acpi_device *device, int type)
 	atk_free_sensors(data);
 	hwmon_device_unregister(data->hwmon_dev);
 
+	kfree(data->buffer);
 	kfree(data);
 
 	return 0;


Luca
-- 
The trouble with computers is that they do what you tell them, 
not what you want.
D. Cohen

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
  2009-09-20 18:58       ` Luca Tettamanti
@ 2009-09-20 22:51         ` Robert Hancock
  -1 siblings, 0 replies; 14+ messages in thread
From: Robert Hancock @ 2009-09-20 22:51 UTC (permalink / raw)
  To: Luca Tettamanti; +Cc: linux-kernel, linux-acpi

On Sun, Sep 20, 2009 at 12:58 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
>> >> I'm guessing this board uses a different format than what the driver
>> >> is expecting. I'm attaching the gzipped decompiled DSDT from the
>> >> board, hopefully it's useful to somebody..
>> >
>> > Please try the following patch, it should detect the proper buffer size.
>> >
>>
>> Obviously something not quite right:
>
> Ah yes, the pointer for the output buffer was pointing to the wrong
> variable. Sorry for that ;)

Cool, seems to be working. Though the high and critical temperatures
seem a bit odd, but maybe that's what the BIOS actually reports:

atk0110-acpi-0
Adapter: ACPI interface
Vcore Voltage:      +1.18 V  (min =  +0.80 V, max =  +1.60 V)
+3.3V Voltage:      +3.44 V  (min =  +2.97 V, max =  +3.63 V)
+5V Voltage:        +5.18 V  (min =  +4.50 V, max =  +5.50 V)
+12V Voltage:      +12.21 V  (min = +10.20 V, max = +13.80 V)
CPU Fan Speed:     1080 RPM  (min =  600 RPM)
Chassis1 Fan Speed:   0 RPM  (min =  600 RPM)
Chassis2 Fan Speed:1464 RPM  (min =  600 RPM)
Power Fan Speed:      0 RPM  (min =    0 RPM)
CPU Temperature:    +32.5°C  (high = +45.0°C, crit = +45.5°C)
MB Temperature:     +31.0°C  (high = +45.0°C, crit = +46.0°C)
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
@ 2009-09-20 22:51         ` Robert Hancock
  0 siblings, 0 replies; 14+ messages in thread
From: Robert Hancock @ 2009-09-20 22:51 UTC (permalink / raw)
  To: Luca Tettamanti; +Cc: linux-kernel, linux-acpi

On Sun, Sep 20, 2009 at 12:58 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
>> >> I'm guessing this board uses a different format than what the driver
>> >> is expecting. I'm attaching the gzipped decompiled DSDT from the
>> >> board, hopefully it's useful to somebody..
>> >
>> > Please try the following patch, it should detect the proper buffer size.
>> >
>>
>> Obviously something not quite right:
>
> Ah yes, the pointer for the output buffer was pointing to the wrong
> variable. Sorry for that ;)

Cool, seems to be working. Though the high and critical temperatures
seem a bit odd, but maybe that's what the BIOS actually reports:

atk0110-acpi-0
Adapter: ACPI interface
Vcore Voltage:      +1.18 V  (min =  +0.80 V, max =  +1.60 V)
+3.3V Voltage:      +3.44 V  (min =  +2.97 V, max =  +3.63 V)
+5V Voltage:        +5.18 V  (min =  +4.50 V, max =  +5.50 V)
+12V Voltage:      +12.21 V  (min = +10.20 V, max = +13.80 V)
CPU Fan Speed:     1080 RPM  (min =  600 RPM)
Chassis1 Fan Speed:   0 RPM  (min =  600 RPM)
Chassis2 Fan Speed:1464 RPM  (min =  600 RPM)
Power Fan Speed:      0 RPM  (min =    0 RPM)
CPU Temperature:    +32.5°C  (high = +45.0°C, crit = +45.5°C)
MB Temperature:     +31.0°C  (high = +45.0°C, crit = +46.0°C)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
  2009-09-20 22:51         ` Robert Hancock
@ 2009-09-21 19:04           ` Luca Tettamanti
  -1 siblings, 0 replies; 14+ messages in thread
From: Luca Tettamanti @ 2009-09-21 19:04 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel, linux-acpi

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF8, Size: 4365 bytes --]

Il Sun, Sep 20, 2009 at 04:51:10PM -0600, Robert Hancock ha scritto: 
> On Sun, Sep 20, 2009 at 12:58 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> >> >> I'm guessing this board uses a different format than what the driver
> >> >> is expecting. I'm attaching the gzipped decompiled DSDT from the
> >> >> board, hopefully it's useful to somebody..
> >> >
> >> > Please try the following patch, it should detect the proper buffer size.
> >> >
> >>
> >> Obviously something not quite right:
> >
> > Ah yes, the pointer for the output buffer was pointing to the wrong
> > variable. Sorry for that ;)
> 
> Cool, seems to be working.

Excellent :)

> Though the high and critical temperatures
> seem a bit odd, but maybe that's what the BIOS actually reports:
[...]
> CPU Temperature:    +32.5°C  (high = +45.0°C, crit = +45.5°C)
> MB Temperature:     +31.0°C  (high = +45.0°C, crit = +46.0°C)

The limits are declared in the DSDT, the driver doesn't do any
calculation.
It's possible that Asus changed the encoding (again); so far I've been
unable to locate a "version" field that would allow the driver to detect
a change in the data structures.

I've got a new patch for you: instead of probing and preallocating the
buffer this version lets ACPI code do the allocation; the return value
is cached anyway, so there won't be a big number of allocations.
Can you please test and see if it works?

diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index fe4fa29..aed6e90 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -129,9 +129,15 @@ struct atk_sensor_data {
 	char const *acpi_name;
 };
 
-struct atk_acpi_buffer_u64 {
-	union acpi_object buf;
-	u64 value;
+/* Return buffer format:
+ * [0-3] "value" is valid flag
+ * [4-7] value
+ * [8- ] unknown stuff on newer mobos
+ */
+struct atk_acpi_ret_buffer {
+	u32 flags;
+	u32 value;
+	u8 data[];
 };
 
 static int atk_add(struct acpi_device *device);
@@ -446,8 +452,10 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	struct acpi_object_list params;
 	struct acpi_buffer ret;
 	union acpi_object id;
-	struct atk_acpi_buffer_u64 tmp;
+	union acpi_object *obj;
+	struct atk_acpi_ret_buffer *buf;
 	acpi_status status;
+	int err = 0;
 
 	id.type = ACPI_TYPE_INTEGER;
 	id.integer.value = sensor->id;
@@ -455,11 +463,7 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	params.count = 1;
 	params.pointer = &id;
 
-	tmp.buf.type = ACPI_TYPE_BUFFER;
-	tmp.buf.buffer.pointer = (u8 *)&tmp.value;
-	tmp.buf.buffer.length = sizeof(u64);
-	ret.length = sizeof(tmp);
-	ret.pointer = &tmp;
+	ret.length = ACPI_ALLOCATE_BUFFER;
 
 	status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
 			&ret, ACPI_TYPE_BUFFER);
@@ -468,23 +472,31 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 				acpi_format_exception(status));
 		return -EIO;
 	}
+	obj = ret.pointer;
 
-	/* Return buffer format:
-	 * [0-3] "value" is valid flag
-	 * [4-7] value
-	 */
-	if (!(tmp.value & 0xffffffff)) {
+	/* Sanity check */
+	if (obj->buffer.length < 8) {
+		dev_warn(dev, "Unexpected ASBF length: %u\n",
+				obj->buffer.length);
+		err = -EIO;
+		goto out;
+	}
+	buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
+
+	if (!buf->flags) {
 		/* The reading is not valid, possible causes:
 		 * - sensor failure
 		 * - enumeration was FUBAR (and we didn't notice)
 		 */
-		dev_info(dev, "Failure: %#llx\n", tmp.value);
-		return -EIO;
+		dev_warn(dev, "Failure: %#x\n", buf->flags);
+		err = -EIO;
+		goto out;
 	}
 
-	*value = (tmp.value & 0xffffffff00000000ULL) >> 32;
-
-	return 0;
+	*value = buf->value;
+out:
+	ACPI_FREE(ret.pointer);
+	return err;
 }
 
 static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)


thanks,
Luca
-- 
"Perché è così che ti frega, la vita. Ti piglia quando hai ancora l'anima
 addormentata e ti semina dentro un'immagine, o un odore, o un suono che
 poi non te lo togli più. E quella lì era la felicità."
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
@ 2009-09-21 19:04           ` Luca Tettamanti
  0 siblings, 0 replies; 14+ messages in thread
From: Luca Tettamanti @ 2009-09-21 19:04 UTC (permalink / raw)
  To: Robert Hancock; +Cc: linux-kernel, linux-acpi

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF8, Size: 4034 bytes --]

Il Sun, Sep 20, 2009 at 04:51:10PM -0600, Robert Hancock ha scritto: 
> On Sun, Sep 20, 2009 at 12:58 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> >> >> I'm guessing this board uses a different format than what the driver
> >> >> is expecting. I'm attaching the gzipped decompiled DSDT from the
> >> >> board, hopefully it's useful to somebody..
> >> >
> >> > Please try the following patch, it should detect the proper buffer size.
> >> >
> >>
> >> Obviously something not quite right:
> >
> > Ah yes, the pointer for the output buffer was pointing to the wrong
> > variable. Sorry for that ;)
> 
> Cool, seems to be working.

Excellent :)

> Though the high and critical temperatures
> seem a bit odd, but maybe that's what the BIOS actually reports:
[...]
> CPU Temperature:    +32.5°C  (high = +45.0°C, crit = +45.5°C)
> MB Temperature:     +31.0°C  (high = +45.0°C, crit = +46.0°C)

The limits are declared in the DSDT, the driver doesn't do any
calculation.
It's possible that Asus changed the encoding (again); so far I've been
unable to locate a "version" field that would allow the driver to detect
a change in the data structures.

I've got a new patch for you: instead of probing and preallocating the
buffer this version lets ACPI code do the allocation; the return value
is cached anyway, so there won't be a big number of allocations.
Can you please test and see if it works?

diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index fe4fa29..aed6e90 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -129,9 +129,15 @@ struct atk_sensor_data {
 	char const *acpi_name;
 };
 
-struct atk_acpi_buffer_u64 {
-	union acpi_object buf;
-	u64 value;
+/* Return buffer format:
+ * [0-3] "value" is valid flag
+ * [4-7] value
+ * [8- ] unknown stuff on newer mobos
+ */
+struct atk_acpi_ret_buffer {
+	u32 flags;
+	u32 value;
+	u8 data[];
 };
 
 static int atk_add(struct acpi_device *device);
@@ -446,8 +452,10 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	struct acpi_object_list params;
 	struct acpi_buffer ret;
 	union acpi_object id;
-	struct atk_acpi_buffer_u64 tmp;
+	union acpi_object *obj;
+	struct atk_acpi_ret_buffer *buf;
 	acpi_status status;
+	int err = 0;
 
 	id.type = ACPI_TYPE_INTEGER;
 	id.integer.value = sensor->id;
@@ -455,11 +463,7 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 	params.count = 1;
 	params.pointer = &id;
 
-	tmp.buf.type = ACPI_TYPE_BUFFER;
-	tmp.buf.buffer.pointer = (u8 *)&tmp.value;
-	tmp.buf.buffer.length = sizeof(u64);
-	ret.length = sizeof(tmp);
-	ret.pointer = &tmp;
+	ret.length = ACPI_ALLOCATE_BUFFER;
 
 	status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
 			&ret, ACPI_TYPE_BUFFER);
@@ -468,23 +472,31 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 				acpi_format_exception(status));
 		return -EIO;
 	}
+	obj = ret.pointer;
 
-	/* Return buffer format:
-	 * [0-3] "value" is valid flag
-	 * [4-7] value
-	 */
-	if (!(tmp.value & 0xffffffff)) {
+	/* Sanity check */
+	if (obj->buffer.length < 8) {
+		dev_warn(dev, "Unexpected ASBF length: %u\n",
+				obj->buffer.length);
+		err = -EIO;
+		goto out;
+	}
+	buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
+
+	if (!buf->flags) {
 		/* The reading is not valid, possible causes:
 		 * - sensor failure
 		 * - enumeration was FUBAR (and we didn't notice)
 		 */
-		dev_info(dev, "Failure: %#llx\n", tmp.value);
-		return -EIO;
+		dev_warn(dev, "Failure: %#x\n", buf->flags);
+		err = -EIO;
+		goto out;
 	}
 
-	*value = (tmp.value & 0xffffffff00000000ULL) >> 32;
-
-	return 0;
+	*value = buf->value;
+out:
+	ACPI_FREE(ret.pointer);
+	return err;
 }
 
 static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)


thanks,
Luca
-- 
"Perché è così che ti frega, la vita. Ti piglia quando hai ancora l'anima
 addormentata e ti semina dentro un'immagine, o un odore, o un suono che
 poi non te lo togli più. E quella lì era la felicità."

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
  2009-09-21 19:04           ` Luca Tettamanti
@ 2009-09-22  0:52             ` Robert Hancock
  -1 siblings, 0 replies; 14+ messages in thread
From: Robert Hancock @ 2009-09-22  0:52 UTC (permalink / raw)
  To: Luca Tettamanti; +Cc: linux-kernel, linux-acpi

On Mon, Sep 21, 2009 at 1:04 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> Il Sun, Sep 20, 2009 at 04:51:10PM -0600, Robert Hancock ha scritto:
>> On Sun, Sep 20, 2009 at 12:58 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
>> >> >> I'm guessing this board uses a different format than what the driver
>> >> >> is expecting. I'm attaching the gzipped decompiled DSDT from the
>> >> >> board, hopefully it's useful to somebody..
>> >> >
>> >> > Please try the following patch, it should detect the proper buffer size.
>> >> >
>> >>
>> >> Obviously something not quite right:
>> >
>> > Ah yes, the pointer for the output buffer was pointing to the wrong
>> > variable. Sorry for that ;)
>>
>> Cool, seems to be working.
>
> Excellent :)
>
>> Though the high and critical temperatures
>> seem a bit odd, but maybe that's what the BIOS actually reports:
> [...]
>> CPU Temperature:    +32.5°C  (high = +45.0°C, crit = +45.5°C)
>> MB Temperature:     +31.0°C  (high = +45.0°C, crit = +46.0°C)
>
> The limits are declared in the DSDT, the driver doesn't do any
> calculation.
> It's possible that Asus changed the encoding (again); so far I've been
> unable to locate a "version" field that would allow the driver to detect
> a change in the data structures.
>
> I've got a new patch for you: instead of probing and preallocating the
> buffer this version lets ACPI code do the allocation; the return value
> is cached anyway, so there won't be a big number of allocations.
> Can you please test and see if it works?

Yes, this version still works..
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: asus_atk0110 not working on Asus P7P55D PRO
@ 2009-09-22  0:52             ` Robert Hancock
  0 siblings, 0 replies; 14+ messages in thread
From: Robert Hancock @ 2009-09-22  0:52 UTC (permalink / raw)
  To: Luca Tettamanti; +Cc: linux-kernel, linux-acpi

On Mon, Sep 21, 2009 at 1:04 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> Il Sun, Sep 20, 2009 at 04:51:10PM -0600, Robert Hancock ha scritto:
>> On Sun, Sep 20, 2009 at 12:58 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
>> >> >> I'm guessing this board uses a different format than what the driver
>> >> >> is expecting. I'm attaching the gzipped decompiled DSDT from the
>> >> >> board, hopefully it's useful to somebody..
>> >> >
>> >> > Please try the following patch, it should detect the proper buffer size.
>> >> >
>> >>
>> >> Obviously something not quite right:
>> >
>> > Ah yes, the pointer for the output buffer was pointing to the wrong
>> > variable. Sorry for that ;)
>>
>> Cool, seems to be working.
>
> Excellent :)
>
>> Though the high and critical temperatures
>> seem a bit odd, but maybe that's what the BIOS actually reports:
> [...]
>> CPU Temperature:    +32.5°C  (high = +45.0°C, crit = +45.5°C)
>> MB Temperature:     +31.0°C  (high = +45.0°C, crit = +46.0°C)
>
> The limits are declared in the DSDT, the driver doesn't do any
> calculation.
> It's possible that Asus changed the encoding (again); so far I've been
> unable to locate a "version" field that would allow the driver to detect
> a change in the data structures.
>
> I've got a new patch for you: instead of probing and preallocating the
> buffer this version lets ACPI code do the allocation; the return value
> is cached anyway, so there won't be a big number of allocations.
> Can you please test and see if it works?

Yes, this version still works..

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2009-09-22  1:18 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-17  5:28 asus_atk0110 not working on Asus P7P55D PRO Robert Hancock
2009-09-17  9:17 ` Luca Tettamanti
2009-09-17  9:17   ` Luca Tettamanti
2009-09-20 16:23 ` Luca Tettamanti
2009-09-20 17:47   ` Robert Hancock
2009-09-20 17:47     ` Robert Hancock
2009-09-20 18:58     ` Luca Tettamanti
2009-09-20 18:58       ` Luca Tettamanti
2009-09-20 22:51       ` Robert Hancock
2009-09-20 22:51         ` Robert Hancock
2009-09-21 19:04         ` Luca Tettamanti
2009-09-21 19:04           ` Luca Tettamanti
2009-09-22  0:52           ` Robert Hancock
2009-09-22  0:52             ` Robert Hancock

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.