* 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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, ¶ms, &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] 8+ 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 2009-09-20 18:58 ` Luca Tettamanti 0 siblings, 1 reply; 8+ 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] 8+ 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 2009-09-20 22:51 ` Robert Hancock 0 siblings, 1 reply; 8+ 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, ¶ms, &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] 8+ 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 2009-09-21 19:04 ` Luca Tettamanti 0 siblings, 1 reply; 8+ 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] 8+ 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 2009-09-22 0:52 ` Robert Hancock 0 siblings, 1 reply; 8+ 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, ¶ms, &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] 8+ 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 0 siblings, 0 replies; 8+ 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] 8+ messages in thread
end of thread, other threads:[~2009-09-22 1:18 UTC | newest] Thread overview: 8+ 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-20 16:23 ` Luca Tettamanti 2009-09-20 17:47 ` Robert Hancock 2009-09-20 18:58 ` Luca Tettamanti 2009-09-20 22:51 ` Robert Hancock 2009-09-21 19:04 ` Luca Tettamanti 2009-09-22 0:52 ` Robert Hancock
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox