From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 08:27:45 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 639DD106564A for ; Sun, 21 Jun 2009 08:27:45 +0000 (UTC) (envelope-from hexanism@gmx.de) Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by mx1.freebsd.org (Postfix) with SMTP id A5AA58FC0C for ; Sun, 21 Jun 2009 08:27:44 +0000 (UTC) (envelope-from hexanism@gmx.de) Received: (qmail invoked by alias); 21 Jun 2009 08:27:42 -0000 Received: from koln-4db4ec1a.pool.einsundeins.de (EHLO phenom.home.network) [77.180.236.26] by mail.gmx.net (mp045) with SMTP; 21 Jun 2009 10:27:42 +0200 X-Authenticated: #12668306 X-Provags-ID: V01U2FsdGVkX19WDkcadalWUuiB5lY9VZSQE0RTiPD6V+oN63pfUj X3DhUaBGZlSkyr Message-ID: <4A3DEEFC.4010204@gmx.de> Date: Sun, 21 Jun 2009 10:27:40 +0200 From: "hexanism@gmx.de" User-Agent: Thunderbird 2.0.0.21 (X11/20090605) MIME-Version: 1.0 To: freebsd-acpi@freebsd.org Content-Type: multipart/mixed; boundary="------------050505060708020706010100" X-Y-GMX-Trusted: 0 X-FuHaFi: 0.53,0.47,0.78,0.77,0.7 Subject: Resume problem (Motherboard: MSI 790GX-G65) X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 08:27:45 -0000 This is a multi-part message in MIME format. --------------050505060708020706010100 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello, I am using suspend/resume (S3) a lot in Linux. Unfortunately I could not get it to work with FreeBSD. I wanted to solve the Problem by trying the hints in the FreeBSD manual. I could not get it to work. Maybe someone can point me in the right direction, I do not have any experience with ACPI/dsdt debugging. The motherboard I am using is a MSI 790GX-G65 featuring the AMD 790 Chipset. This model is quite a new AM3 board. It has an onboard 3D-accelerated AMD graphics card. The Bios is up to date (Revision 1.3). I am using FreeBSD 7.2-RC2 with the generic kernel (I also did all the testing with another hardrive using FreeBSD 7.2-RELEASE). Suspend and resume work with Linux (Ubuntu 9.04) and Windows XP 64 flawlessly. S1 freezes the screen about two seconds after calling "acpiconf -s 1". Then I have to press the reset button. S3/suspend seems to work. The Fans and drives turn off and the power led acts exactly the same way as it acts under Linux and Windows. Under Linux/Windows I can resume by Keyboard. Under FreeBSD that does not work, I have to press the power button to get the computer to react. Unfortunately the screen stays black (drives and fans do get turned on). I have to press the reset button. I inspected the dsdt of my motherboard: http://innoits.de/chris-msi790gx65.asl There are a lot of errors when recompiling with iasl (about 180 Errors, most of them "Object does not exist"). I downloaded the ACPI specifications (3.0a, 3.0b and 4.0) but could not fix the Errors (I started with the first one ;)) due to my lack of knowledge concerning ACPI. What can I do now? Most of the errors are of the same type. I hope that ther is a simple solution that I just can't solve by myself. Is there a good beginner friendly dsdt tutorial around? Is it possible that the dsdt of my motherboard uses a newer ACPI revision (4.0) and thus is incompatible with the current version of iasl? Thank you very much for reading this... Chris --------------050505060708020706010100 Content-Type: text/plain; name="dmesg.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dmesg.txt" Copyright (c) 1992-2009 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD is a registered trademark of The FreeBSD Foundation. FreeBSD 7.2-RC2 #0: Fri Jun 5 09:46:42 CEST 2009 root@phenom.home.network:/usr/obj/usr/src/sys/GENERIC Timecounter "i8254" frequency 1193182 Hz quality 0 CPU: AMD Phenom(tm) II X3 720 Processor (2807.08-MHz 686-class CPU) Origin = "AuthenticAMD" Id = 0x100f42 Stepping = 2 Features=0x178bfbff Features2=0x802009 AMD Features=0xee500800 AMD Features2=0x37ff,,,Prefetch,,,,> TSC: P-state invariant Cores per package: 3 real memory = 3489202176 (3327 MB) avail memory = 3409829888 (3251 MB) ACPI APIC Table: <7576MS A7576100> FreeBSD/SMP: Multiprocessor System Detected: 3 CPUs cpu0 (BSP): APIC ID: 0 cpu1 (AP): APIC ID: 1 cpu2 (AP): APIC ID: 2 ACPI Warning (tbfadt-0505): Optional field "Pm2ControlBlock" has zero address or length: 0 0/1 [20070320] ioapic0 irqs 0-23 on motherboard kbd1 at kbdmux0 acpi0: <7576MS A7576100> on motherboard acpi0: [ITHREAD] acpi0: Power Button (fixed) acpi0: reservation of fee00000, 1000 (3) failed acpi0: reservation of ffb80000, 80000 (3) failed acpi0: reservation of fec10000, 20 (3) failed acpi0: reservation of 0, a0000 (3) failed acpi0: reservation of 100000, cff00000 (3) failed ACPI HPET table warning: Sequence is non-zero (2) Timecounter "ACPI-fast" frequency 3579545 Hz quality 1000 acpi_timer0: <32-bit timer at 3.579545MHz> port 0x808-0x80b on acpi0 acpi_hpet0: iomem 0xfed00000-0xfed003ff on acpi0 Timecounter "HPET" frequency 14318180 Hz quality 900 pcib0: port 0xcf8-0xcff on acpi0 pci0: on pcib0 pcib1: at device 1.0 on pci0 pci1: on pcib1 vgapci0: port 0xc000-0xc0ff mem 0xd0000000-0xdfffffff,0xfe9f0000-0xfe9fffff,0xfe800000-0xfe8fffff irq 18 at device 5.0 on pci1 drm0: on vgapci0 vgapci0: child drm0 requested pci_enable_busmaster info: [drm] Initialized radeon 1.29.0 20080528 pcib2: irq 17 at device 5.0 on pci0 pci2: on pcib2 re0: port 0xd800-0xd8ff mem 0xfeaff000-0xfeafffff,0xfdffc000-0xfdffffff irq 17 at device 0.0 on pci2 re0: Using 1 MSI messages re0: Chip rev. 0x28000000 re0: MAC rev. 0x00000000 miibus0: on re0 rgephy0: PHY 1 on miibus0 rgephy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT, 1000baseT-FDX, auto re0: Ethernet address: 00:24:21:26:7e:45 re0: [FILTER] pcib3: irq 18 at device 6.0 on pci0 pci3: on pcib3 fwohci0: <1394 Open Host Controller Interface> port 0xe800-0xe8ff mem 0xfebff800-0xfebfffff irq 18 at device 0.0 on pci3 fwohci0: [FILTER] fwohci0: OHCI version 1.10 (ROM=1) fwohci0: No. of Isochronous channels is 4. fwohci0: EUI64 00:10:dc:00:01:90:3b:2e fwohci0: Phy 1394a available S400, 2 ports. fwohci0: Link S400, max_rec 2048 bytes. firewire0: on fwohci0 fwe0: on firewire0 if_fwe0: Fake Ethernet address: 02:10:dc:90:3b:2e fwe0: Ethernet address: 02:10:dc:90:3b:2e fwip0: on firewire0 fwip0: Firewire address: 00:10:dc:00:01:90:3b:2e @ 0xfffe00000000, S400, maxrec 2048 sbp0: on firewire0 dcons_crom0: on firewire0 dcons_crom0: bus_addr 0x1094000 fwohci0: Initiate bus reset fwohci0: BUS reset fwohci0: node_id=0xc800ffc0, gen=1, CYCLEMASTER mode atapci0: port 0xb000-0xb007,0xa000-0xa003,0x9000-0x9007,0x8000-0x8003,0x7000-0x700f mem 0xfe7ffc00-0xfe7fffff irq 22 at device 17.0 on pci0 atapci0: [ITHREAD] atapci0: AHCI Version 01.10 controller with 4 ports detected ata2: on atapci0 ata2: [ITHREAD] ata3: on atapci0 ata3: [ITHREAD] ata4: on atapci0 ata4: [ITHREAD] ata5: on atapci0 ata5: [ITHREAD] ohci0: mem 0xfe7fe000-0xfe7fefff irq 16 at device 18.0 on pci0 ohci0: [GIANT-LOCKED] ohci0: [ITHREAD] usb0: OHCI version 1.0, legacy support usb0: SMM does not respond, resetting usb0: on ohci0 usb0: USB revision 1.0 uhub0: on usb0 uhub0: 3 ports with 3 removable, self powered ohci1: mem 0xfe7fd000-0xfe7fdfff irq 16 at device 18.1 on pci0 ohci1: [GIANT-LOCKED] ohci1: [ITHREAD] usb1: OHCI version 1.0, legacy support usb1: SMM does not respond, resetting usb1: on ohci1 usb1: USB revision 1.0 uhub1: on usb1 uhub1: 3 ports with 3 removable, self powered ehci0: mem 0xfe7ff800-0xfe7ff8ff irq 17 at device 18.2 on pci0 ehci0: [GIANT-LOCKED] ehci0: [ITHREAD] usb2: EHCI version 1.0 usb2: companion controllers, 3 ports each: usb0 usb1 usb2: on ehci0 usb2: USB revision 2.0 uhub2: on usb2 uhub2: 6 ports with 6 removable, self powered ohci2: mem 0xfe7fc000-0xfe7fcfff irq 18 at device 19.0 on pci0 ohci2: [GIANT-LOCKED] ohci2: [ITHREAD] usb3: OHCI version 1.0, legacy support usb3: SMM does not respond, resetting usb3: on ohci2 usb3: USB revision 1.0 uhub3: on usb3 uhub3: 3 ports with 3 removable, self powered ohci3: mem 0xfe7fb000-0xfe7fbfff irq 18 at device 19.1 on pci0 ohci3: [GIANT-LOCKED] ohci3: [ITHREAD] usb4: OHCI version 1.0, legacy support usb4: SMM does not respond, resetting usb4: on ohci3 usb4: USB revision 1.0 uhub4: on usb4 uhub4: 3 ports with 3 removable, self powered ehci1: mem 0xfe7ff400-0xfe7ff4ff irq 19 at device 19.2 on pci0 ehci1: [GIANT-LOCKED] ehci1: [ITHREAD] usb5: EHCI version 1.0 usb5: companion controllers, 3 ports each: usb3 usb4 usb5: on ehci1 usb5: USB revision 2.0 uhub5: on usb5 uhub5: 6 ports with 6 removable, self powered pci0: at device 20.0 (no driver attached) atapci1: port 0x1f0-0x1f7,0x3f6,0x170-0x177,0x376,0xff00-0xff0f at device 20.1 on pci0 ata0: on atapci1 ata0: [ITHREAD] hdac0: mem 0xfe7f4000-0xfe7f7fff irq 16 at device 20.2 on pci0 hdac0: HDA Driver Revision: 20090329_0131 hdac0: [ITHREAD] isab0: at device 20.3 on pci0 isa0: on isab0 pcib4: at device 20.4 on pci0 pci4: on pcib4 ohci4: mem 0xfe7fa000-0xfe7fafff irq 18 at device 20.5 on pci0 ohci4: [GIANT-LOCKED] ohci4: [ITHREAD] usb6: OHCI version 1.0, legacy support usb6: SMM does not respond, resetting usb6: on ohci4 usb6: USB revision 1.0 uhub6: on usb6 uhub6: 2 ports with 2 removable, self powered acpi_button0: on acpi0 atkbdc0: port 0x60,0x64 irq 1 on acpi0 atkbd0: irq 1 on atkbdc0 kbd0 at atkbd0 atkbd0: [GIANT-LOCKED] atkbd0: [ITHREAD] sio0: <16550A-compatible COM port> port 0x3f8-0x3ff irq 4 flags 0x10 on acpi0 sio0: type 16550A sio0: [FILTER] fdc0: port 0x3f0-0x3f5,0x3f7 irq 6 drq 2 on acpi0 fdc0: [FILTER] fd0: <1440-KB 3.5" drive> on fdc0 drive 0 cpu0: on acpi0 acpi_throttle0: on cpu0 cpu1: on acpi0 cpu2: on acpi0 pmtimer0 on isa0 ppc0: parallel port not found. sc0: at flags 0x100 on isa0 sc0: VGA <16 virtual consoles, flags=0x300> sio1: configured irq 3 not in bitmap of probed irqs 0 sio1: port may not be enabled vga0: at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0 ukbd0: on uhub0 kbd2 at ukbd0 ums0: on uhub4 ums0: 4 buttons and Z dir. Timecounters tick every 1.000 msec firewire0: 1 nodes, maxhop <= 0, cable IRM = 0 (me) firewire0: bus manager 0 (me) ad4: 610480MB at ata2-master SATA300 ad6: 476940MB at ata3-master SATA300 acd0: DVDR at ata4-master SATA150 hdac0: HDA Codec #3: Realtek ALC889 pcm0: at cad 3 nid 1 on hdac0 pcm1: at cad 3 nid 1 on hdac0 pcm2: at cad 3 nid 1 on hdac0 pcm3: at cad 3 nid 1 on hdac0 SMP: AP CPU #2 Launched! SMP: AP CPU #1 Launched! GEOM_LABEL: Label for provider acd0 is iso9660/COD2DVD. GEOM_LABEL: Label for provider ad6s1 is ufsid/47bfa940baa976b0. GEOM_LABEL: Label for provider ad4s2a is ufsid/4a0421dbf6c33b7f. GEOM_LABEL: Label for provider ad4s2d is ufsid/4a0421de783ef232. GEOM_LABEL: Label for provider ad4s2e is ufsid/4a0421db6fb07dcc. GEOM_LABEL: Label for provider ad4s2f is ufsid/4a0421db9ffdbb73. Trying to mount root from ufs:/dev/ad4s2a GEOM_LABEL: Label ufsid/4a0421dbf6c33b7f removed. GEOM_LABEL: Label for provider ad4s2a is ufsid/4a0421dbf6c33b7f. GEOM_LABEL: Label ufsid/4a0421db6fb07dcc removed. GEOM_LABEL: Label ufsid/47bfa940baa976b0 removed. GEOM_LABEL: Label for provider ad4s2e is ufsid/4a0421db6fb07dcc. GEOM_LABEL: Label for provider ad6s1 is ufsid/47bfa940baa976b0. GEOM_LABEL: Label ufsid/4a0421db9ffdbb73 removed. GEOM_LABEL: Label for provider ad4s2f is ufsid/4a0421db9ffdbb73. GEOM_LABEL: Label ufsid/4a0421de783ef232 removed. GEOM_LABEL: Label for provider ad4s2d is ufsid/4a0421de783ef232. GEOM_LABEL: Label ufsid/4a0421dbf6c33b7f removed. GEOM_LABEL: Label ufsid/4a0421db6fb07dcc removed. GEOM_LABEL: Label ufsid/4a0421db9ffdbb73 removed. GEOM_LABEL: Label ufsid/4a0421de783ef232 removed. GEOM_LABEL: Label ufsid/47bfa940baa976b0 removed. vgapci0: child drm0 requested pci_disable_busmaster drm0: detached kldunload: attempt to unload file that was loaded by the kernel pcm0: detached pcm1: detached pcm2: detached pcm3: detached hdac0: detached --------------050505060708020706010100 Content-Type: text/plain; name="kldstat.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="kldstat.txt" Id Refs Address Size Name 1 3 0xc0400000 9fab28 kernel 6 1 0xc0ed9000 6a45c acpi.ko --------------050505060708020706010100 Content-Type: text/plain; name="sysctl_hw_acpi.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sysctl_hw_acpi.txt" hw.acpi.supported_sleep_state: S1 S3 S4 S5 hw.acpi.power_button_state: S5 hw.acpi.sleep_button_state: S1 hw.acpi.lid_switch_state: NONE hw.acpi.standby_state: S1 hw.acpi.suspend_state: S3 hw.acpi.sleep_delay: 1 hw.acpi.s4bios: 0 hw.acpi.verbose: 0 hw.acpi.disable_on_reboot: 0 hw.acpi.handle_reboot: 0 hw.acpi.reset_video: 0 hw.acpi.cpu.cx_lowest: C1 --------------050505060708020706010100 Content-Type: text/plain; name="uname_a.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="uname_a.txt" FreeBSD phenom.home.network 7.2-RC2 FreeBSD 7.2-RC2 #0: Fri Jun 5 09:46:42 CEST 2009 root@phenom.home.network:/usr/obj/usr/src/sys/GENERIC i386 --------------050505060708020706010100 Content-Type: text/plain; name="acpidump_warning.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="acpidump_warning.txt" acpidump: RSDT entry 3 (sig OEMB) is corrupt --------------050505060708020706010100-- From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 11:48:10 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7EFDB1065673 for ; Sun, 21 Jun 2009 11:48:10 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 3A6638FC18 for ; Sun, 21 Jun 2009 11:48:07 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 74082 invoked by uid 89); 21 Jun 2009 11:21:25 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.188.39) by mail.bindone.de with ESMTPA; 21 Jun 2009 11:21:25 -0000 Message-ID: <4A3E1784.2050406@bindone.de> Date: Sun, 21 Jun 2009 13:20:36 +0200 From: Michael User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: freebsd-acpi@freebsd.org Content-Type: multipart/mixed; boundary="------------000106060507010904000207" Cc: c.r.n.a@wanadoo.fr, "Paul B. Mahol" Subject: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 11:48:10 -0000 This is a multi-part message in MIME format. --------------000106060507010904000207 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hello, I wrote two new acpi modules last year and finally found the time to fix them, add some missing features and write man pages. This is the first time I'm writing kernel code for FreeBSD, so please excuse me if I failed to apply to all style conventions (I tried to follow style(9) as closely as possible). acpi_wmi is an ACPI to WMI mapping driver (this is used by HP and Acer notebooks and potentially others), so this could also be used to implement additional drivers on (see for more details on WMI and ACPI: http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx). It provides /dev/wmistat, example output: cat /dev/wmistat GUID INST EXPE METH STR EVENT OID {5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA {95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - {2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - {05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB {1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA {2D114B49-2DFB-4130-B8FE-4A3C09E75133} 57 NO NO NO NO BC {988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 20 NO NO NO NO BD {14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE {322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF {8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG {8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH {8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI acpi_hp is a driver that uses acpi_wmi to provide HP specific features. These include: - Activate/deactivate WLAN - Activate/deactivate WWAN - Activate/deactivate Bluetooth - Auto activate/deactiavte based on hw radio status - Devd notifications - On air status for different - Controls ambient light sensor - Get docking status - Read BIOS settings through /dev/hpcmi, example output: Flash Media Reader Disable USB Ports including Express Card slot Enable 1394 Port Enable Cardbus Slot Disable Express Card Slot Disable F9, F10 and F12 Delay(Sec) 0 USB Device Detection Delay (Sec) 0 Multiboot Enable Express Boot Popup Delay(Sec) 0 CD-ROM Boot Enable Floppy Boot Disable Internal Network Adapter Boot Disable Internal Network Adapter Boot Mode PXE Swap Fn/Ctrl Key Disable USB Legacy Support Disable Parallel Port Mode ECP ... The man pages included in the patch (man acpi_hp / man acpi_wmi) give you detailed information about all sysctls and devices. The patch attached (acpi_wmi_and_acpi_hp.patch) has been tested against 7.2-RELEASE and everything compiles cleanly, although my tests have been on 8-CURRENT (but the snapshot is older than 7.2), so I expect this to work ok on 7.2. The patch might fail against CURRENT though, this is why I also attached patches.tgz, which contains individual patches per file. I only tested this on i386 and the patch only changes i386 specific things (I have no idea if this could possibly work on amd64, especially because all the other acpi_support modules seem to be i386 only). Also note, that I could only test this on my own machine (HP Compaq 8510p), which features WLAN/BT/WLAN, so I don't know if the readings will be sane if your machine doesn't feature a WWAN chip. In theory this should work for many different HP models. Installation instructions (replace MYKERNEL with your kernel name): mkdir /usr/src/sys/modules/acpi/acpi_wmi mkdir /usr/src/sys/modules/acpi/acpi_hp patch -d /usr/src < acpi_wmi_and_acpi_hp.patch cd /usr/src/share/man/man4/man4.i386 make all && make install cd /usr/src/sys/i386/conf config MYKERNEL cd ../compile/MYKERNEL make cleandepend && make depend make all make install reboot . . . kldload acpi_hp cat /dev/wmistat sysctl -a | grep acpi_hp.0 sysctl dev.acpi_hp.0.als = 0 cat /dev/hpcmi sysctl dev.acpi_hp.0.cmi_detail=7 cat /dev/hpcmi It would be nice to get some feedback on this and maybe someone else can implement vendor specific ACPI modules for other WMI based laptops now. cheers Michael --------------000106060507010904000207 Content-Type: text/plain; name="acpi_wmi_and_acpi_hp.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="acpi_wmi_and_acpi_hp.patch" --- sys/i386/conf/NOTES~ 2008-12-29 04:48:16.000000000 +0100 +++ sys/i386/conf/NOTES 2009-06-21 12:10:16.000000000 +0100 @@ -471,6 +471,9 @@ options ACPI_DEBUG #!options ACPI_NO_SEMAPHORES +# ACPI WMI Mapping driver +device acpi_wmi + # ACPI Asus Desktop Extras. (voltage, temp, fan) device acpi_aiboost @@ -480,6 +483,9 @@ # ACPI Fujitsu Extras (Buttons) device acpi_fujitsu +# ACPI extras driver for HP laptops +device acpi_hp + # ACPI extras driver for IBM laptops device acpi_ibm --- sys/modules/acpi/Makefile~ 2008-12-29 04:41:59.000000000 +0100 +++ sys/modules/acpi/Makefile 2009-06-21 12:10:59.000000000 +0100 @@ -4,7 +4,7 @@ SUBDIR= acpi .endif -SUBDIR+= acpi_aiboost acpi_asus acpi_fujitsu acpi_ibm \ +SUBDIR+= acpi_wmi acpi_aiboost acpi_asus acpi_fujitsu acpi_hp acpi_ibm \ acpi_panasonic acpi_sony acpi_toshiba acpi_video \ acpi_dock --- share/man/man4/man4.i386/acpi_hp.4~ 2009-06-21 12:09:58.000000000 +0200 +++ share/man/man4/man4.i386/acpi_hp.4 2009-06-21 12:10:21.229934511 +0200 @@ -0,0 +1,273 @@ +.\" Copyright (c) 2009 Michael Gmelin +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 21, 2009 +.Dt ACPI_HP 4 i386 +.Os +.Sh NAME +.Nm acpi_hp +.Nd "ACPI extras driver for HP laptops" +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following line in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device acpi_hp" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +acpi_hp_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides support for ACPI-controlled features found on HP laptops +that use a WMI enabled BIOS (e.g. HP Compaq 8510p and 6510p). +.Pp +The main purpose of this driver is to provide an interface, +accessible via +.Xr sysctl 8 , +.Xr devd 8 and +.Xr devfs 8 , +through which applications can determine and change the status of +various laptop components and BIOS settings. +.Pp +.Ss Xr devd 8 Ss Events +Devd events received by +.Xr devd 8 +provide the following information: +.Pp +.Bl -tag -width "subsystem" -offset indent -compact +.It system +.Qq Li ACPI +.It subsystem +.Qq Li HP +.It type +The source of the event in the ACPI namespace. +The value depends on the model. +.It notify +Event code (see below). +.El +.Pp +Event codes: +.Pp +.Bl -tag -width "0xc0" -offset indent -compact +.It Li 0xc0 +WLAN on air status changed to 0 (not on air) +.It Li 0xc1 +WLAN on air status changed to 1 (on air) +.It Li 0xd0 +Bluetooth on air status changed to 0 (not on air) +.It Li 0xd1 +Bluetooth on air status changed to 1 (on air) +.It Li 0xe0 +WWAN on air status changed to 0 (not on air) +.It Li 0xe1 +WWAN on air status changed to 1 (on air) +.El +.Ss Xr devfs 8 Ss Device +You can read /dev/hpcmi to see your current BIOS settings. The detail level +can be adjusted by setting the sysctl +.Va cmi_detail +as described below. +.Sh SYSCTL VARIABLES +The following sysctls are currently implemented: +.Ss WLAN: +.Bl -tag -width indent +.It Va dev.acpi_hp.0.wlan_enabled +Toggle WLAN chip activity. +.It Va dev.acpi_hp.0.wlan_radio +(read-only) +WLAN radio status (controlled by hardware switch) +.It Va dev.acpi_hp.0.wlan_on_air +(read-only) +WLAN on air (chip enabled, hardware switch enabled + enabled in BIOS) +.It Va dev.acpi_hp.0.wlan_enabled_if_radio_on +If set to 1, the WLAN chip will be enabled if the radio is turned on +.It Va dev.acpi_hp.0.wlan_disable_if_radio_off +If set to 1, the WLAN chip will be disabled if the radio is turned off +.El +.Ss Bluetooth: +.Bl -tag -width indent +.It Va dev.acpi_hp.0.bt_enabled +Toggle Bluetooth chip activity. +.It Va dev.acpi_hp.0.bt_radio +(read-only) +Bluetooth radio status (controlled by hardware switch) +.It Va dev.acpi_hp.0.bt_on_air +(read-only) +Bluetooth on air (chip enabled, hardware switch enabled + enabled in BIOS) +.It Va dev.acpi_hp.0.bt_enabled_if_radio_on +If set to 1, the Bluetooth chip will be enabled if the radio is turned on +.It Va dev.acpi_hp.0.bt_disable_if_radio_off +If set to 1, the Bluetooth chip will be disabled if the radio is turned off +.El +.Ss WWAN: +.Bl -tag -width indent +.It Va dev.acpi_hp.0.wwan_enabled +Toggle WWAN chip activity. +.It Va dev.acpi_hp.0.wwan_radio +(read-only) +WWAN radio status (controlled by hardware switch) +.It Va dev.acpi_hp.0.wwan_on_air +(read-only) +WWAN on air (chip enabled, hardware switch enabled + enabled in BIOS) +.It Va dev.acpi_hp.0.wwan_enabled_if_radio_on +If set to 1, the WWAN chip will be enabled if the radio is turned on +.It Va dev.acpi_hp.0.wwan_disable_if_radio_off +If set to 1, the WWAN chip will be disabled if the radio is turned off +.El +.Ss Misc: +.Bl -tag -width indent +.It Va dev.acpi_hp.0.als_enabled +Toggle ambient light sensor (ALS) +.It Va dev.acpi_hp.0.display +(read-only) +Display status (bitmask) +.It Va dev.acpi_hp.0.hdd_temperature +(read-only) +HDD temperature +.It Va dev.acpi_hp.0.is_docked +(read-only) +Docking station status (1 if docked) +.It Va dev.acpi_hp.0.cmi_detail +Bitmask to control detail level in /dev/hpcmi output (values can be ORed). +.Bl -tag -width "0x01" -offset indent -compact +.It Li 0x01 +Show path component of BIOS setting +.It Li 0x02 +Show a list of valid options for the BIOS setting +.It Li 0x04 +Show additional flags of BIOS setting (ReadOnly etc.) +.El +.El +.Pp +Defaults for these sysctls can be set in +.Xr sysctl.conf 5 . +.Sh FILES +.Bl -tag -width ".Pa /dev/hpcmi" +.It Pa /dev/hpcmi +Interface to read BIOS settings +.El +.Sh EXAMPLES +The following can be added to +.Xr devd.conf 5 +in order disable the LAN interface when WLAN on air and reenable if it's +not: +.Bd -literal -offset indent +notify 0 { + match "system" "ACPI"; + match "subsystem" "HP"; + match "notify" "0xc0"; + action "ifconfig em0 up"; +}; + +notify 0 { + match "system" "ACPI"; + match "subsystem" "HP"; + match "notify" "0xc1"; + action "ifconfig em0 down"; +}; +.Ed +.Pp +Enable the ambient light sensor: +.Bd -literal -offset indent +sysctl dev.acpi_hp.0.als_enabled=1 +.Ed +.Pp +Enable Bluetooth: +.Bd -literal -offset indent +sysctl dev.acpi_hp.0.bt_enabled=1 +.Ed +.Pp +Get BIOS settings: +.Bd -literal -offset indent +cat /dev/hpcmi + +Serial Port Disable +Infrared Port Enable +Parallel Port Disable +Flash Media Reader Disable +USB Ports including Express Card slot Enable +1394 Port Enable +Cardbus Slot Disable +Express Card Slot Disable +(...) +.Ed +.Pp +Set maximum detail level for /dev/hpcmi output: +.Bd -literal -offset indent +sysctl dev.acpi_hp.0.cmi_detail=7 +.Ed +.Pp + + + +.Sh SEE ALSO +.Xr acpi 4 , +.Xr acpi_wmi 4 , +.Xr sysctl.conf 5 , +.Xr devd 8 , +.Xr devfs 8 , +.Xr sysctl 8 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Fx CURRENT . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Michael Gmelin Aq freebsd@grem.de +.Pp +It has been inspired by hp-wmi driver, which implements a subset of these +features (hotkeys) on Linux. +.Pp +.Bl -tag -width indent +.It HP CMI whitepaper: +http://h20331.www2.hp.com/Hpsub/downloads/cmi_whitepaper.pdf +.It wmi-hp for Linux: +http://www.kernel.org +.It WMI and ACPI: +http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx +.El +.Pp +This manual page was written by +.An Michael Gmelin Aq freebsd@grem.de +.Sh BUGS +This driver is experimental and has only been tested on CURRENT i386 on an +HP Compaq 8510p which featured all supported wireless devices (WWAN/BT/WLAN). +Expect undefined results when operating on different hardware. +.Pp +Loading the driver is slow. Reading from /dev/hpcmi is even slower. +.Pp +Additional features like HP specific sensor readings or writing BIOS +settings are not supported. --- sys/dev/acpi_support/acpi_hp.c~ 2009-06-21 12:09:58.000000000 +0200 +++ sys/dev/acpi_support/acpi_hp.c 2009-06-21 12:10:55.256712496 +0200 @@ -0,0 +1,1042 @@ +/*- + * Copyright (c) 2009 Michael Gmelin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * Driver for extra ACPI-controlled features found on HP laptops + * that use a WMI enabled BIOS (e.g. HP Compaq 8510p and 6510p). + * Allows to control and read status of integrated hardware and read + * BIOS settings through CMI. + * Inspired by the hp-wmi driver, which implements a subset of these + * features (hotkeys) on Linux. + * + * HP CMI whitepaper: http://h20331.www2.hp.com/Hpsub/downloads/cmi_whitepaper.pdf + * wmi-hp for Linux: http://www.kernel.org + * WMI and ACPI: http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx + */ + +#include "opt_acpi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "acpi_wmi_if.h" + +#define _COMPONENT ACPI_OEM +ACPI_MODULE_NAME("HP") + +#define ACPI_HP_WMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" +#define ACPI_HP_WMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" +#define ACPI_HP_WMI_CMI_GUID "2D114B49-2DFB-4130-B8FE-4A3C09E75133" + +#define ACPI_HP_WMI_DISPLAY_COMMAND 0x1 +#define ACPI_HP_WMI_HDDTEMP_COMMAND 0x2 +#define ACPI_HP_WMI_ALS_COMMAND 0x3 +#define ACPI_HP_WMI_DOCK_COMMAND 0x4 +#define ACPI_HP_WMI_WIRELESS_COMMAND 0x5 + +#define ACPI_HP_METHOD_WLAN_ENABLED 1 +#define ACPI_HP_METHOD_WLAN_RADIO 2 +#define ACPI_HP_METHOD_WLAN_ON_AIR 3 +#define ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON 4 +#define ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF 5 +#define ACPI_HP_METHOD_BLUETOOTH_ENABLED 6 +#define ACPI_HP_METHOD_BLUETOOTH_RADIO 7 +#define ACPI_HP_METHOD_BLUETOOTH_ON_AIR 8 +#define ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON 9 +#define ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF 10 +#define ACPI_HP_METHOD_WWAN_ENABLED 11 +#define ACPI_HP_METHOD_WWAN_RADIO 12 +#define ACPI_HP_METHOD_WWAN_ON_AIR 13 +#define ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON 14 +#define ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF 15 +#define ACPI_HP_METHOD_ALS 16 +#define ACPI_HP_METHOD_DISPLAY 17 +#define ACPI_HP_METHOD_HDDTEMP 18 +#define ACPI_HP_METHOD_DOCK 19 +#define ACPI_HP_METHOD_CMI_DETAIL 20 + +#define HP_MASK_WWAN_ON_AIR 0x1000000 +#define HP_MASK_BLUETOOTH_ON_AIR 0x10000 +#define HP_MASK_WLAN_ON_AIR 0x100 +#define HP_MASK_WWAN_RADIO 0x8000000 +#define HP_MASK_BLUETOOTH_RADIO 0x80000 +#define HP_MASK_WLAN_RADIO 0x800 +#define HP_MASK_WWAN_ENABLED 0x2000000 +#define HP_MASK_BLUETOOTH_ENABLED 0x20000 +#define HP_MASK_WLAN_ENABLED 0x200 + +#define ACPI_HP_CMI_DETAIL_PATHS 0x01 +#define ACPI_HP_CMI_DETAIL_ENUMS 0x02 +#define ACPI_HP_CMI_DETAIL_FLAGS 0x04 + +struct acpi_hp_inst_seq_pair { + UINT32 sequence; /* sequence number as suggested by cmi bios */ + UINT8 instance; /* object instance on guid */ +}; + +struct acpi_hp_softc { + device_t dev; + ACPI_HANDLE handle; + device_t wmi_dev; + int has_notify; /* notification GUID found */ + int has_cmi; /* CMI GUID found */ + int cmi_detail; /* CMI detail level (controlled by sysctl) */ + int wlan_enable_if_radio_on; /* controlled by sysctl */ + int wlan_disable_if_radio_off; /* controlled by sysctl */ + int bluetooth_enable_if_radio_on; /* controlled by sysctl */ + int bluetooth_disable_if_radio_off; /* controlled by sysctl */ + int wwan_enable_if_radio_on; /* controlled by sysctl */ + int wwan_disable_if_radio_off; /* controlled by sysctl */ + int was_wlan_on_air; /* last known WLAN on air status */ + int was_bluetooth_on_air; /* last known Bluetooth in air status */ + int was_wwan_on_air; /* last known WWAN on air status */ + struct sysctl_ctx_list *sysctl_ctx; + struct sysctl_oid *sysctl_tree; + struct cdev *hpcmi_dev_t; /* hpcmi device handle */ + struct sbuf hpcmi_sbuf; /* /dev/hpcmi output sbuf */ + pid_t hpcmi_open_pid; /* pid operating on /dev/hpcmi */ + int hpcmi_bufptr; /* current pointer position in /dev/hpcmi output buffer */ + int cmi_order_size; /* size of cmi_order list */ + struct acpi_hp_inst_seq_pair cmi_order[128]; /* list of CMI instances ordered by BIOS suggested sequence */ +}; + +static struct { + char *name; + int method; + char *description; + int access; +} acpi_hp_sysctls[] = { + { + .name = "wlan_enabled", + .method = ACPI_HP_METHOD_WLAN_ENABLED, + .description = "Enable/Disable WLAN (WiFi)", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wlan_radio", + .method = ACPI_HP_METHOD_WLAN_RADIO, + .description = "WLAN radio status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "wlan_on_air", + .method = ACPI_HP_METHOD_WLAN_ON_AIR, + .description = "WLAN radio ready to use (enabled and radio)", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "wlan_enable_if_radio_on", + .method = ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON, + .description = "Enable WLAN if radio is turned on", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wlan_disable_if_radio_off", + .method = ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF, + .description = "Disable WLAN if radio is turned off", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "bt_enabled", + .method = ACPI_HP_METHOD_BLUETOOTH_ENABLED, + .description = "Enable/Disable Bluetooth", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "bt_radio", + .method = ACPI_HP_METHOD_BLUETOOTH_RADIO, + .description = "Bluetooth radio status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "bt_on_air", + .method = ACPI_HP_METHOD_BLUETOOTH_ON_AIR, + .description = "Bluetooth radio ready to use (enabled and radio)", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "bt_enable_if_radio_on", + .method = ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON, + .description = "Enable bluetooth if radio is turned on", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "bt_disable_if_radio_off", + .method = ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF, + .description = "Disable bluetooth if radio is turned off", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wwan_enabled", + .method = ACPI_HP_METHOD_WWAN_ENABLED, + .description = "Enable/Disable WWAN (UMTS)", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wwan_radio", + .method = ACPI_HP_METHOD_WWAN_RADIO, + .description = "WWAN radio status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "wwan_on_air", + .method = ACPI_HP_METHOD_WWAN_ON_AIR, + .description = "WWAN radio ready to use (enabled and radio)", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "wwan_enable_if_radio_on", + .method = ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON, + .description = "Enable WWAN if radio is turned on", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wwan_disable_if_radio_off", + .method = ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF, + .description = "Disable WWAN if radio is turned off", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "als_enabled", + .method = ACPI_HP_METHOD_ALS, + .description = "Enable/Disable ALS (Ambient light sensor)", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "display", + .method = ACPI_HP_METHOD_DISPLAY, + .description = "Display status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "hdd_temperature", + .method = ACPI_HP_METHOD_HDDTEMP, + .description = "HDD temperature", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "is_docked", + .method = ACPI_HP_METHOD_DOCK, + .description = "Docking station status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "cmi_detail", + .method = ACPI_HP_METHOD_CMI_DETAIL, + .description = "Details shown in CMI output (cat /dev/hpcmi)", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + + { NULL, 0, NULL, 0 } +}; + +ACPI_SERIAL_DECL(hp, "HP ACPI-WMI Mapping"); + +static int acpi_hp_probe(device_t dev); +static int acpi_hp_attach(device_t dev); +static int acpi_hp_detach(device_t dev); + +static void acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc* sc); +static int acpi_hp_sysctl(SYSCTL_HANDLER_ARGS); +static int acpi_hp_sysctl_set(struct acpi_hp_softc *sc, int method, int arg, int oldarg); +static int acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method); +static int acpi_hp_exec_wmi_command(device_t wmi_dev, int command, int is_write, int val); +static void acpi_hp_notify(ACPI_HANDLE h, UINT32 notify, void *context); +static int acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, UINT8 instance, + char* outbuf, size_t outsize, UINT32* sequence, int detail); +static void acpi_hp_hex_decode(char* buffer); + +static d_open_t acpi_hp_hpcmi_open; +static d_close_t acpi_hp_hpcmi_close; +static d_read_t acpi_hp_hpcmi_read; + +/* handler /dev/hpcmi device */ +static struct cdevsw hpcmi_cdevsw = { + .d_version = D_VERSION, + .d_open = acpi_hp_hpcmi_open, + .d_close = acpi_hp_hpcmi_close, + .d_read = acpi_hp_hpcmi_read, + .d_name = "hpcmi", +}; + +static device_method_t acpi_hp_methods[] = { + DEVMETHOD(device_probe, acpi_hp_probe), + DEVMETHOD(device_attach, acpi_hp_attach), + DEVMETHOD(device_detach, acpi_hp_detach), + {0, 0} +}; + +static driver_t acpi_hp_driver = { + "acpi_hp", + acpi_hp_methods, + sizeof(struct acpi_hp_softc), +}; + +static devclass_t acpi_hp_devclass; + +DRIVER_MODULE(acpi_hp, acpi, acpi_hp_driver, acpi_hp_devclass, + 0, 0); +MODULE_DEPEND(acpi_hp, acpi_wmi, 1, 1, 1); +MODULE_DEPEND(acpi_hp, acpi, 1, 1, 1); + +static void +acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc *sc) +{ + int wireless; + int new_wlan_status; + int new_bluetooth_status; + int new_wwan_status; + + wireless = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + new_wlan_status = -1; + new_bluetooth_status = -1; + new_wwan_status = -1; + + device_printf(sc->wmi_dev, "Wireless status is %x\n", wireless); + if (sc->wlan_disable_if_radio_off && !(wireless & HP_MASK_WLAN_RADIO) && (wireless & HP_MASK_WLAN_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x100); + new_wlan_status = 0; + } + else if (sc->wlan_enable_if_radio_on && (wireless & HP_MASK_WLAN_RADIO) && !(wireless & HP_MASK_WLAN_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x101); + new_wlan_status = 1; + } + if (sc->bluetooth_disable_if_radio_off && !(wireless & HP_MASK_BLUETOOTH_RADIO) && (wireless & HP_MASK_BLUETOOTH_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x200); + new_bluetooth_status = 0; + } + else if (sc->bluetooth_enable_if_radio_on && (wireless & HP_MASK_BLUETOOTH_RADIO) && !(wireless & HP_MASK_BLUETOOTH_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x202); + new_bluetooth_status = 1; + } + if (sc->wwan_disable_if_radio_off && !(wireless & HP_MASK_WWAN_RADIO) && (wireless & HP_MASK_WWAN_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x400); + new_wwan_status = 0; + } + else if (sc->wwan_enable_if_radio_on && (wireless & HP_MASK_WWAN_RADIO) && !(wireless & HP_MASK_WWAN_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x404); + new_wwan_status = 1; + } + + if (new_wlan_status == -1) { + new_wlan_status = (wireless & HP_MASK_WLAN_ON_AIR); + if ((new_wlan_status?1:0) != sc->was_wlan_on_air) { + sc->was_wlan_on_air = sc->was_wlan_on_air?0:1; + device_printf(sc->wmi_dev, "WLAN on air changed to %i (new_wlan_status is %i)\n", sc->was_wlan_on_air, new_wlan_status); + acpi_UserNotify("HP", sc->handle, 0xc0+sc->was_wlan_on_air); + } + } + if (new_bluetooth_status == -1) { + new_bluetooth_status = (wireless & HP_MASK_BLUETOOTH_ON_AIR); + if ((new_bluetooth_status?1:0) != sc->was_bluetooth_on_air) { + sc->was_bluetooth_on_air = sc->was_bluetooth_on_air?0:1; + device_printf(sc->wmi_dev, "BLUETOOTH on air changed to %i (new_bluetooth_status is %i)\n", sc->was_bluetooth_on_air, new_bluetooth_status); + acpi_UserNotify("HP", sc->handle, 0xd0+sc->was_bluetooth_on_air); + } + } + if (new_wwan_status == -1) { + new_wwan_status = (wireless & HP_MASK_WWAN_ON_AIR); + if ((new_wwan_status?1:0) != sc->was_wwan_on_air) { + sc->was_wwan_on_air = sc->was_wwan_on_air?0:1; + device_printf(sc->wmi_dev, "WWAN on air changed to %i (new_wwan_status is %i)\n", sc->was_wwan_on_air, new_wwan_status); + acpi_UserNotify("HP", sc->handle, 0xe0+sc->was_wwan_on_air); + } + } +} + +static int +acpi_hp_probe(device_t dev) +{ + if (acpi_disabled("hp") || device_get_unit(dev) != 0) + return (ENXIO); + device_set_desc(dev, "HP ACPI-WMI Mapping"); + return (0); +} + +static int +acpi_hp_attach(device_t dev) +{ + struct acpi_hp_softc *sc; + struct acpi_softc *acpi_sc; + devclass_t wmi_devclass; + int arg; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); + + sc = device_get_softc(dev); + sc->dev = dev; + sc->handle = acpi_get_handle(dev); + sc->has_notify = 0; + sc->has_cmi = 0; + sc->bluetooth_enable_if_radio_on = 0; + sc->bluetooth_disable_if_radio_off = 0; + sc->wlan_enable_if_radio_on = 0; + sc->wlan_disable_if_radio_off = 0; + sc->wlan_enable_if_radio_on = 0; + sc->wlan_disable_if_radio_off = 0; + sc->was_wlan_on_air = 0; + sc->was_bluetooth_on_air = 0; + sc->was_wwan_on_air = 0; + sc->cmi_detail = 0; + sc->cmi_order_size = -1; + memset(sc->cmi_order, 0, sizeof(sc->cmi_order)); + acpi_sc = acpi_device_get_parent_softc(dev); + + if (!(wmi_devclass = devclass_find ("acpi_wmi"))) { + device_printf(dev, "Couldn't find acpi_wmi devclass\n"); + return (EINVAL); + } + if (!(sc->wmi_dev = devclass_get_device(wmi_devclass, 0))) { + device_printf(dev, "Couldn't find acpi_wmi device\n"); + return (EINVAL); + } + if (!ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_BIOS_GUID)) { + device_printf(dev, "WMI device does not provide the HP BIOS GUID\n"); + return (EINVAL); + } + if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_EVENT_GUID)) { + device_printf(dev, "HP event GUID detected, installing event handler\n"); + if (ACPI_WMI_INSTALL_EVENT_HANDLER(sc->wmi_dev, ACPI_HP_WMI_EVENT_GUID, acpi_hp_notify, dev)) { + device_printf(dev, "Could not install notification handler!\n"); + } + else { + sc->has_notify = 1; + } + } + if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID)) { + device_printf(dev, "HP CMI GUID detected\n"); + sc->has_cmi = 1; + } + + if (sc->has_cmi) { + sc->hpcmi_dev_t = make_dev(&hpcmi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "hpcmi"); + sc->hpcmi_dev_t->si_drv1 = sc; + sc->hpcmi_open_pid = 0; + sc->hpcmi_bufptr = -1; + } + + ACPI_SERIAL_BEGIN(hp); + + sc->sysctl_ctx = device_get_sysctl_ctx(dev); + sc->sysctl_tree = device_get_sysctl_tree(dev); + for (int i = 0; acpi_hp_sysctls[i].name != NULL; ++i) { + arg = 0; + if ((!sc->has_notify && + (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON || + acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF || + acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON || + acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF || + acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON || + acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF)) || + (arg = acpi_hp_sysctl_get(sc, acpi_hp_sysctls[i].method)) < 0) { + continue; + } + if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_ON_AIR) { + sc->was_wlan_on_air = arg; + } + else if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_ON_AIR) { + sc->was_bluetooth_on_air = arg; + } + else if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_ON_AIR) { + sc->was_wwan_on_air = arg; + } + + SYSCTL_ADD_PROC(sc->sysctl_ctx, + SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, + acpi_hp_sysctls[i].name, acpi_hp_sysctls[i].access, + sc, i, acpi_hp_sysctl, "I", + acpi_hp_sysctls[i].description); + } + ACPI_SERIAL_END(hp); + + return (0); +} + +static int +acpi_hp_detach(device_t dev) +{ + int ret; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); + struct acpi_hp_softc *sc = device_get_softc(dev); + if (sc->has_cmi && sc->hpcmi_open_pid != 0) { + ret = EBUSY; + } + else { + if (sc->has_notify) { + ACPI_WMI_REMOVE_EVENT_HANDLER(dev, ACPI_HP_WMI_EVENT_GUID); + } + if (sc->hpcmi_bufptr != -1) { + sbuf_delete(&sc->hpcmi_sbuf); + sc->hpcmi_bufptr = -1; + } + sc->hpcmi_open_pid = 0; + destroy_dev(sc->hpcmi_dev_t); + ret = 0; + } + return (ret); +} + +static int +acpi_hp_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct acpi_hp_softc *sc; + int arg; + int oldarg; + int error = 0; + int function; + int method; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = (struct acpi_hp_softc *)oidp->oid_arg1; + function = oidp->oid_arg2; + method = acpi_hp_sysctls[function].method; + + ACPI_SERIAL_BEGIN(hp); + arg = acpi_hp_sysctl_get(sc, method); + oldarg = arg; + error = sysctl_handle_int(oidp, &arg, 0, req); + if (!error && req->newptr != NULL) { + error = acpi_hp_sysctl_set(sc, method, arg, oldarg); + } + ACPI_SERIAL_END(hp); + + return (error); +} + +static int +acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method) +{ + int val = 0; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + ACPI_SERIAL_ASSERT(hp); + + switch (method) { + case ACPI_HP_METHOD_WLAN_ENABLED: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WLAN_ENABLED) != 0); + break; + case ACPI_HP_METHOD_WLAN_RADIO: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WLAN_RADIO) != 0); + break; + case ACPI_HP_METHOD_WLAN_ON_AIR: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WLAN_ON_AIR) != 0); + break; + case ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON: + val = sc->wlan_enable_if_radio_on; + break; + case ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF: + val = sc->wlan_disable_if_radio_off; + break; + case ACPI_HP_METHOD_BLUETOOTH_ENABLED: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_BLUETOOTH_ENABLED) != 0); + break; + case ACPI_HP_METHOD_BLUETOOTH_RADIO: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_BLUETOOTH_RADIO) != 0); + break; + case ACPI_HP_METHOD_BLUETOOTH_ON_AIR: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_BLUETOOTH_ON_AIR) != 0); + break; + case ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON: + val = sc->bluetooth_enable_if_radio_on; + break; + case ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF: + val = sc->bluetooth_disable_if_radio_off; + break; + case ACPI_HP_METHOD_WWAN_ENABLED: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WWAN_ENABLED) != 0); + break; + case ACPI_HP_METHOD_WWAN_RADIO: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WWAN_RADIO) != 0); + break; + case ACPI_HP_METHOD_WWAN_ON_AIR: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WWAN_ON_AIR) != 0); + break; + case ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON: + val = sc->wwan_enable_if_radio_on; + break; + case ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF: + val = sc->wwan_disable_if_radio_off; + break; + case ACPI_HP_METHOD_ALS: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_ALS_COMMAND, 0, 0); + break; + case ACPI_HP_METHOD_DISPLAY: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_DISPLAY_COMMAND, 0, 0); + break; + case ACPI_HP_METHOD_HDDTEMP: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_HDDTEMP_COMMAND, 0, 0); + break; + case ACPI_HP_METHOD_DOCK: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_DOCK_COMMAND, 0, 0); + break; + case ACPI_HP_METHOD_CMI_DETAIL: + val = sc->cmi_detail; + break; + } + return (val); +} + +static int +acpi_hp_sysctl_set(struct acpi_hp_softc *sc, int method, int arg, int oldarg) +{ + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + ACPI_SERIAL_ASSERT(hp); + + if (method != ACPI_HP_METHOD_CMI_DETAIL) + arg = arg?1:0; + + if (arg != oldarg) { + switch (method) { + case ACPI_HP_METHOD_WLAN_ENABLED: + return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x101:0x100)); + case ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON: + sc->wlan_enable_if_radio_on = arg; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF: + sc->wlan_disable_if_radio_off = arg; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_BLUETOOTH_ENABLED: + return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x202:0x200)); + case ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON: + sc->bluetooth_enable_if_radio_on = arg; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF: + sc->bluetooth_disable_if_radio_off = arg?1:0; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_WWAN_ENABLED: + return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x404:0x400)); + case ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON: + sc->wwan_enable_if_radio_on = arg?1:0; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF: + sc->wwan_disable_if_radio_off = arg?1:0; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_ALS: + return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_ALS_COMMAND, 1, arg?1:0)); + case ACPI_HP_METHOD_CMI_DETAIL: + sc->cmi_detail = arg; + break; + } + } + return (0); +} + +static __inline void acpi_hp_free_buffer(ACPI_BUFFER* buf) { + if (buf && buf->Pointer) { + AcpiOsFree(buf->Pointer); + } +} + +static void +acpi_hp_notify(ACPI_HANDLE h, UINT32 notify, void *context) +{ + device_t dev = context; + ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); + + struct acpi_hp_softc *sc = device_get_softc(dev); + ACPI_BUFFER response = { ACPI_ALLOCATE_BUFFER, NULL }; + ACPI_OBJECT *obj; + ACPI_WMI_GET_EVENT_DATA(sc->wmi_dev, notify, &response); + obj = (ACPI_OBJECT*) response.Pointer; + if (obj && obj->Type == ACPI_TYPE_BUFFER && obj->Buffer.Length == 8) { + if (*((UINT8 *) obj->Buffer.Pointer) == 0x5) { + acpi_hp_evaluate_auto_on_off(sc); + } + } + acpi_hp_free_buffer(&response); +} + +static int +acpi_hp_exec_wmi_command(device_t wmi_dev, int command, int is_write, int val) +{ + UINT32 params[5] = {0x55434553, is_write?2:1, command, is_write?4:0, val}; + UINT32* result; + ACPI_OBJECT *obj; + ACPI_BUFFER in = { sizeof(params), ¶ms }; + ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; + int retval; + + if (ACPI_FAILURE(ACPI_WMI_EVALUATE_CALL(wmi_dev, ACPI_HP_WMI_BIOS_GUID, 0, 0x3, &in, &out))) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } + obj = out.Pointer; + if (!obj || obj->Type != ACPI_TYPE_BUFFER) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } + result = (UINT32*) obj->Buffer.Pointer; + retval = result[2]; + if (result[1] > 0) { + retval = result[1]; + } + acpi_hp_free_buffer(&out); + return (retval); +} + +static __inline char* acpi_hp_get_string_from_object(ACPI_OBJECT* obj, char* dst, size_t size) { + int length; + dst[0] = 0; + if (obj->Type == ACPI_TYPE_STRING) { + length = obj->String.Length+1; + if (length > size) { + length = size - 1; + } + strlcpy(dst, obj->String.Pointer, length); + acpi_hp_hex_decode(dst); + } + return (dst); +} + + +/* + * Read BIOS Setting block in instance "instance". + * The block returned is ACPI_TYPE_PACKAGE which should contain the following elements: + * Index Meaning + * 0 Setting Name [string] + * 1 Value (comma separated, asterisk marks the current value) [string] + * 2 Path within the bios hierarchy [string] + * 3 IsReadOnly [int] + * 4 DisplayInUI [int] + * 5 RequiresPhysicalPresence [int] + * 6 Sequence for ordering within the bios settings (absolute) [int] + * 7 Length of prerequisites array [int] + * 8 Prerequisite1 [string] + * 9 Prerequisite2 [string] + * 10 Prerequisite3 [string] + * 11 Current value (in case of enum) [string] / Array length [int] + * 12 Enum length [int] / Array values + * 13ff Enum value at index x [string] + */ +static int +acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, UINT8 instance, char* outbuf, size_t outsize, UINT32* sequence, int detail) +{ + ACPI_OBJECT *obj; + ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; + int i; + int outlen; + int size = 255; + int has_enums = 0; + char string_buffer[size]; + int enumbase; + + outlen = 0; + outbuf[0] = 0; + if (ACPI_FAILURE(ACPI_WMI_GET_BLOCK(wmi_dev, guid, instance, &out))) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } + obj = out.Pointer; + if (!obj && obj->Type != ACPI_TYPE_PACKAGE) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } + + /* check if this matches our expectations based on our limited knowledge */ + if (obj->Package.Count >= 13 && + obj->Package.Elements[0].Type == ACPI_TYPE_STRING && + obj->Package.Elements[1].Type == ACPI_TYPE_STRING && + obj->Package.Elements[2].Type == ACPI_TYPE_STRING && + obj->Package.Elements[3].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[4].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[5].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[6].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[7].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[8].Type == ACPI_TYPE_STRING && + obj->Package.Elements[9].Type == ACPI_TYPE_STRING && + obj->Package.Elements[10].Type == ACPI_TYPE_STRING && + ((obj->Package.Elements[11].Type == ACPI_TYPE_STRING && + obj->Package.Elements[12].Type == ACPI_TYPE_INTEGER && + obj->Package.Count >= 13+obj->Package.Elements[12].Integer.Value) || + (obj->Package.Elements[11].Type == ACPI_TYPE_INTEGER && + obj->Package.Count >= 12+obj->Package.Elements[11].Integer.Value)) + ) { + enumbase = obj->Package.Elements[11].Type == ACPI_TYPE_STRING?12:11; + if (detail & ACPI_HP_CMI_DETAIL_PATHS) { + strlcat(outbuf, acpi_hp_get_string_from_object(&obj->Package.Elements[2], string_buffer, size), outsize); + outlen += 48; + while (strlen(outbuf) < outlen) + strlcat(outbuf, " ", outsize); + } + strlcat(outbuf, acpi_hp_get_string_from_object(&obj->Package.Elements[0], string_buffer, size), outsize); + outlen += 43; + while (strlen(outbuf) < outlen) + strlcat(outbuf, " ", outsize); + if (enumbase == 12) + strlcat(outbuf, acpi_hp_get_string_from_object(&obj->Package.Elements[11], string_buffer, size), outsize); + outlen += 21; + while (strlen(outbuf) < outlen) + strlcat(outbuf, " ", outsize); + for (i = 0; i < strlen(outbuf); ++i) + if (outbuf[i] == '\\') + outbuf[i] = '/'; + if (detail & ACPI_HP_CMI_DETAIL_ENUMS) { + for (i = enumbase+1; i < enumbase+1 + obj->Package.Elements[enumbase].Integer.Value; ++i) { + acpi_hp_get_string_from_object(&obj->Package.Elements[i], string_buffer, size); + if (strlen(string_buffer) > 1 || (strlen(string_buffer) == 1 && string_buffer[0] != ' ')) { + if (has_enums) + strlcat(outbuf, "/", outsize); + else + strlcat(outbuf, " (", outsize); + strlcat(outbuf, string_buffer, outsize); + has_enums = 1; + } + } + } + if (has_enums) + strlcat(outbuf, ")", outsize); + if (detail & ACPI_HP_CMI_DETAIL_FLAGS) { + strlcat(outbuf, obj->Package.Elements[3].Integer.Value?" [ReadOnly]":"", outsize); + strlcat(outbuf, obj->Package.Elements[4].Integer.Value?"":" [NOUI]", outsize); + strlcat(outbuf, obj->Package.Elements[5].Integer.Value?" [RPP]":"", outsize); + } + *sequence = (UINT32) obj->Package.Elements[6].Integer.Value; + } + acpi_hp_free_buffer(&out); + return (0); +} + + + +/* + * Convert given two digit hex string (hexin) to an UINT8 referenced + * by byteout. + * Return != 0 if the was a problem (invalid input) + */ +static __inline int acpi_hp_hex_to_int(const UINT8 *hexin, UINT8 *byteout) +{ + unsigned int hi; + unsigned int lo; + + hi = hexin[0]; + lo = hexin[1]; + if ('0' <= hi && hi <= '9') + hi -= '0'; + else if ('A' <= hi && hi <= 'F') + hi -= ('A' - 10); + else if ('a' <= hi && hi <= 'f') + hi -= ('a' - 10); + else + return (1); + if ('0' <= lo && lo <= '9') + lo -= '0'; + else if ('A' <= lo && lo <= 'F') + lo -= ('A' - 10); + else if ('a' <= lo && lo <= 'f') + lo -= ('a' - 10); + else + return (1); + *byteout = (hi << 4) + lo; + return (0); +} + + +static void +acpi_hp_hex_decode(char* buffer) +{ + int i; + int length = strlen(buffer); + UINT8 *uin; + UINT8 uout; + + if (((int)length/2)*2 == length || length < 10) return; + + for (i = 0; i= '0' && buffer[i] <= '9') || + (buffer[i] >= 'A' && buffer[i] <= 'F'))) + return; + } + + for (i = 0; isi_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(hp); + if (sc->hpcmi_open_pid != 0) { + ret = EBUSY; + } + else { + if (sbuf_new(&sc->hpcmi_sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) { + ret = ENXIO; + } else { + sc->hpcmi_open_pid = td->td_proc->p_pid; + sc->hpcmi_bufptr = 0; + ret = 0; + } + } + ACPI_SERIAL_END(hp); + return (ret); +} + +/* + * close hpcmi device + */ +static int +acpi_hp_hpcmi_close(struct cdev* dev, int flags, int mode, struct thread *td) +{ + struct acpi_hp_softc *sc; + int ret; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(hp); + if (sc->hpcmi_open_pid == 0) { + ret = EBADF; + } + else { + if (sc->hpcmi_bufptr != -1) { + sbuf_delete(&sc->hpcmi_sbuf); + sc->hpcmi_bufptr = -1; + } + sc->hpcmi_open_pid = 0; + ret = 0; + } + ACPI_SERIAL_END(hp); + return (ret); +} + +/* + * Read from hpcmi bios information + */ +static int +acpi_hp_hpcmi_read(struct cdev *dev, struct uio *buf, int flag) +{ + struct acpi_hp_softc *sc; + int pos, i, l, ret; + UINT8 instance; + UINT32 sequence; + int linesize = 1025; + char line[linesize]; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(hp); + if (sc->hpcmi_open_pid != buf->uio_td->td_proc->p_pid || sc->hpcmi_bufptr == -1) { + ret = EBADF; + } + else { + if (!sbuf_done(&sc->hpcmi_sbuf)) { + if (sc->cmi_order_size < 0) { + sc->cmi_order_size = 0; + for (instance = 0; instance < 128; ++instance) { + if (acpi_hp_get_cmi_block(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID, instance, line, linesize, &sequence, sc->cmi_detail)) { + instance = 128; + } + else { + pos = sc->cmi_order_size; + for (i=0; icmi_order_size && i<127; ++i) { + if (sc->cmi_order[i].sequence > sequence) { + pos = i; + break; + } + } + for (i=sc->cmi_order_size; i>pos; --i) { + sc->cmi_order[i].sequence = sc->cmi_order[i-1].sequence; + sc->cmi_order[i].instance = sc->cmi_order[i-1].instance; + } + sc->cmi_order[pos].sequence = sequence; + sc->cmi_order[pos].instance = instance; + sc->cmi_order_size++; + } + } + } + for (i=0; icmi_order_size; ++i) { + if (!acpi_hp_get_cmi_block(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID, sc->cmi_order[i].instance, line, linesize, &sequence, sc->cmi_detail)) { + sbuf_printf(&sc->hpcmi_sbuf, "%s\n", line); + } + } + sbuf_finish(&sc->hpcmi_sbuf); + } + if (sbuf_len(&sc->hpcmi_sbuf) <= 0) { + sbuf_delete(&sc->hpcmi_sbuf); + sc->hpcmi_bufptr = -1; + sc->hpcmi_open_pid = 0; + ret = ENOMEM; + } else { + l = min(buf->uio_resid, sbuf_len(&sc->hpcmi_sbuf) - sc->hpcmi_bufptr); + ret = (l > 0)?uiomove(sbuf_data(&sc->hpcmi_sbuf) + sc->hpcmi_bufptr, l, buf) : 0; + sc->hpcmi_bufptr += l; + } + } + ACPI_SERIAL_END(hp); + return (ret); +} --- share/man/man4/man4.i386/acpi_wmi.4~ 2009-06-21 12:09:58.000000000 +0200 +++ share/man/man4/man4.i386/acpi_wmi.4 2009-06-21 12:10:57.178932778 +0200 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2009 Michael Gmelin +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 21, 2009 +.Dt ACPI_WMI 4 i386 +.Os +.Sh NAME +.Nm acpi_wmi +.Nd "ACPI to WMI mapping driver" +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following line in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device acpi_wmi" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +acpi_wmi_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides an interface for vendor specific WMI implementations +(e.g. HP and Acer laptops). It creates /dev/wmistat, which can be read to get +information about GUIDs found in the system. +.Sh FILES +.Bl -tag -width /dev/wmistat -compact +.It Pa /dev/wmistat +WMI status device. +.El +.Sh EXAMPLES +.Bd Literal +root# cat /dev/wmistat + +GUID INST EXPE METH STR EVENT OID +{5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA +{95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - +{2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - +{05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB +{1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA +{2D114B49-2DFB-4130-B8FE-4A3C09E75133} 57 NO NO NO NO BC +{988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 20 NO NO NO NO BD +{14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE +{322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF +{8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG +{8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH +{8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI +.Ed + +.Sh SEE ALSO +.Xr acpi 4 , +.Sh HISTORY +The +.Nm +device driver first appeared in +.Fx CURRENT . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Michael Gmelin Aq freebsd@grem.de +.Pp +Work has been inspired by the Linux acpi-wmi driver written by Carlos Corbacho +.Pp +See http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx for +the specification of ACPI-WMI. +.Pp +This manual page was written by +.An Michael Gmelin Aq freebsd@grem.de --- sys/dev/acpi_support/acpi_wmi.c~ 2009-06-21 12:09:58.000000000 +0200 +++ sys/dev/acpi_support/acpi_wmi.c 2009-06-21 12:10:26.901562330 +0200 @@ -0,0 +1,911 @@ +/*- + * Copyright (c) 2009 Michael Gmelin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * Driver for acpi-wmi mapping, provides an interface for vendor specific + * implementations (e.g. HP and Acer laptops). + * Inspired by the ACPI-WMI mapping driver (c) 2008-2008 Carlos Corbacho which + * implements this functionality for Linux. + * + * WMI and ACPI: http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx + * acpi-wmi for Linux: http://www.kernel.org + */ + +#include "opt_acpi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "acpi_wmi_if.h" + +MALLOC_DEFINE(M_ACPIWMI, "acpiwmi", "ACPI-WMI mapping"); + +#define _COMPONENT ACPI_OEM +ACPI_MODULE_NAME("ACPI_WMI"); + +#define ACPI_WMI_REGFLAG_EXPENSIVE 0x1 /* GUID flag: Expensive operation */ +#define ACPI_WMI_REGFLAG_METHOD 0x2 /* GUID flag: Method call */ +#define ACPI_WMI_REGFLAG_STRING 0x4 /* GUID flag: String */ +#define ACPI_WMI_REGFLAG_EVENT 0x8 /* GUID flag: Event */ + +/* + * acpi_wmi driver private structure + */ +struct acpi_wmi_softc { + device_t wmi_dev; /* wmi device id */ + ACPI_HANDLE wmi_handle; /* handle of the PNP0C14 node */ + device_t ec_dev; /* acpi_ec0 */ + struct cdev *wmistat_dev_t; /* wmistat device handle */ + struct sbuf wmistat_sbuf; /* sbuf for /dev/wmistat output */ + pid_t wmistat_open_pid; /* pid currently operating in /dev/wmistat */ + int wmistat_bufptr; /* /dev/wmistat ptr to current buffer position */ +}; + +/* + * Struct that holds information about + * about a single GUID entry in _WDG + */ +struct guid_info { + char guid[16]; /* 16 byte non human readable GUID */ + char oid[2]; /* object id or event notify id (first byte) */ + UINT8 max_instance; /* highest instance known for this GUID */ + UINT8 flags; /* ACPI_WMI_REGFLAG_%s */ +}; + +/* WExx event generation state (on/off) */ +enum event_generation_state { + EVENT_GENERATION_ON = 1, + EVENT_GENERATION_OFF = 0 +}; + + +/* + * Information about one entry in _WDG. + * List of those is used to lookup information by GUID. + */ +struct wmi_info { + TAILQ_ENTRY(wmi_info) wmi_list; + struct guid_info ginfo; /* information on guid */ + ACPI_NOTIFY_HANDLER event_handler; /* client provided event handler */ + void *event_handler_user_data; /* cookie to send when calling event_handler */ +}; +TAILQ_HEAD(wmi_info_list_head, wmi_info) wmi_info_list = TAILQ_HEAD_INITIALIZER(wmi_info_list); + +ACPI_SERIAL_DECL(acpi_wmi, "ACPI-WMI Mapping"); + +/* public interface - declaration */ +/* standard device interface*/ +static int acpi_wmi_probe(device_t dev); +static int acpi_wmi_attach(device_t dev); +static int acpi_wmi_detach(device_t dev); +/* see acpi_wmi_if.m */ +static int acpi_wmi_provides_guid_string_method(device_t dev, const char *guid_string); +static ACPI_STATUS acpi_wmi_evaluate_call_method(device_t dev, const char *guid_string, + UINT8 instance, UINT32 method_id, const ACPI_BUFFER *in, ACPI_BUFFER *out); +static ACPI_STATUS acpi_wmi_install_event_handler_method(device_t dev, const char *guid_string, + ACPI_NOTIFY_HANDLER handler, void *data); +static ACPI_STATUS acpi_wmi_remove_event_handler_method(device_t dev, const char *guid_string); +static ACPI_STATUS acpi_wmi_get_event_data_method(device_t dev, UINT32 event_id, ACPI_BUFFER *out); +static ACPI_STATUS acpi_wmi_get_block_method(device_t dev, const char *guid_string, + UINT8 instance, ACPI_BUFFER *out); +static ACPI_STATUS acpi_wmi_set_block_method(device_t dev, const char *guid_string, + UINT8 instance, const ACPI_BUFFER *in); +/* private interface - declaration */ +/* callbacks */ +static void acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context); +static ACPI_STATUS acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, + UINT32 width, ACPI_INTEGER *value, void *context, + void *region_context); +/* helpers */ +static ACPI_STATUS acpi_wmi_read_wdg_blocks(ACPI_HANDLE h); +static ACPI_STATUS acpi_wmi_toggle_we_event_generation(device_t dev, struct wmi_info *winfo, + enum event_generation_state state); +static int acpi_wmi_guid_string_to_guid(const UINT8 *guid_string, UINT8 *guid); +static struct wmi_info* acpi_wmi_lookup_wmi_info_by_guid_string(const char *guid_string); + +static d_open_t acpi_wmi_wmistat_open; +static d_close_t acpi_wmi_wmistat_close; +static d_read_t acpi_wmi_wmistat_read; + +/* handler /dev/wmistat device */ +static struct cdevsw wmistat_cdevsw = { + .d_version = D_VERSION, + .d_open = acpi_wmi_wmistat_open, + .d_close = acpi_wmi_wmistat_close, + .d_read = acpi_wmi_wmistat_read, + .d_name = "wmistat", +}; + + +static device_method_t acpi_wmi_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, acpi_wmi_probe), + DEVMETHOD(device_attach, acpi_wmi_attach), + DEVMETHOD(device_detach, acpi_wmi_detach), + + /* acpi_wmi interface */ + DEVMETHOD(acpi_wmi_provides_guid_string, acpi_wmi_provides_guid_string_method), + DEVMETHOD(acpi_wmi_evaluate_call, acpi_wmi_evaluate_call_method), + DEVMETHOD(acpi_wmi_install_event_handler, acpi_wmi_install_event_handler_method), + DEVMETHOD(acpi_wmi_remove_event_handler, acpi_wmi_remove_event_handler_method), + DEVMETHOD(acpi_wmi_get_event_data, acpi_wmi_get_event_data_method), + DEVMETHOD(acpi_wmi_get_block, acpi_wmi_get_block_method), + DEVMETHOD(acpi_wmi_set_block, acpi_wmi_set_block_method), + + {0, 0} +}; + +static driver_t acpi_wmi_driver = { + "acpi_wmi", + acpi_wmi_methods, + sizeof(struct acpi_wmi_softc), +}; + +static devclass_t acpi_wmi_devclass; +DRIVER_MODULE(acpi_wmi, acpi, acpi_wmi_driver, acpi_wmi_devclass, 0, 0); +MODULE_VERSION(acpi_wmi, 1); +MODULE_DEPEND(acpi_wmi, acpi, 1, 1, 1); +static char *wmi_ids[] = {"PNP0C14", "PNP0c14", NULL}; + +/* + * Probe for the PNP0C14 ACPI node + */ +static int +acpi_wmi_probe(device_t dev) +{ + if (acpi_disabled("wmi") || + ACPI_ID_PROBE(device_get_parent(dev), dev, wmi_ids) == NULL) + return (ENXIO); + device_set_desc(dev, "ACPI-WMI mapping"); + return (0); +} + +/* + * Attach the device by: + * - Looking for the first ACPI EC device + * - Install the notify handler + * - Install the EC address space handler + * - Look for the _WDG node and read GUID information blocks + */ +static int +acpi_wmi_attach(device_t dev) +{ + struct acpi_wmi_softc *sc; + int ret; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + sc = device_get_softc(dev); + ret = ENXIO; + + ACPI_SERIAL_BEGIN(acpi_wmi); + sc->wmi_dev = dev; + sc->wmi_handle = acpi_get_handle(dev); + TAILQ_INIT(&wmi_info_list); + /* XXX Only works with one EC, but nearly all systems only have one. */ + if ((sc->ec_dev = devclass_get_device(devclass_find("acpi_ec"), 0)) == NULL) + device_printf(dev, "cannot find EC device\n"); + else if (ACPI_FAILURE((status = AcpiInstallNotifyHandler(sc->wmi_handle, + ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler, sc)))) + device_printf(sc->wmi_dev, "couldn't install notify handler - %s\n", AcpiFormatException(status)); + else if (ACPI_FAILURE((status = AcpiInstallAddressSpaceHandler(sc->wmi_handle, + ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler, NULL, sc)))) { + device_printf(sc->wmi_dev, "couldn't install EC handler - %s\n", AcpiFormatException(status)); + AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler); + } else if (ACPI_FAILURE((status = acpi_wmi_read_wdg_blocks(sc->wmi_handle)))) { + device_printf(sc->wmi_dev, "couldn't parse _WDG - %s\n", AcpiFormatException(status)); + AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler); + AcpiRemoveAddressSpaceHandler(sc->wmi_handle, ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler); + } else { + sc->wmistat_dev_t = make_dev(&wmistat_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "wmistat"); + sc->wmistat_dev_t->si_drv1 = sc; + sc->wmistat_open_pid = 0; + sc->wmistat_bufptr = -1; + ret = 0; + } + ACPI_SERIAL_END(acpi_wmi); + return (ret); +} + +/* + * Detach the driver by: + * - Removing notification handler + * - Removing address space handler + * - Turning off event generation for all WExx event activated by + * child drivers + */ +static int +acpi_wmi_detach(device_t dev) +{ + struct wmi_info *winfo, *tmp; + struct acpi_wmi_softc *sc; + int ret; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + sc = device_get_softc(dev); + ACPI_SERIAL_BEGIN(acpi_wmi); + + if (sc->wmistat_open_pid != 0) { + ret = EBUSY; + } else { + AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler); + AcpiRemoveAddressSpaceHandler(sc->wmi_handle, ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler); + TAILQ_FOREACH_SAFE(winfo, &wmi_info_list, wmi_list, tmp) { + if (winfo->event_handler) + acpi_wmi_toggle_we_event_generation(dev, winfo, EVENT_GENERATION_OFF); + TAILQ_REMOVE(&wmi_info_list, winfo, wmi_list); + free(winfo, M_ACPIWMI); + } + if (sc->wmistat_bufptr != -1) { + sbuf_delete(&sc->wmistat_sbuf); + sc->wmistat_bufptr = -1; + } + sc->wmistat_open_pid = 0; + destroy_dev(sc->wmistat_dev_t); + ret = 0; + } + ACPI_SERIAL_END(acpi_wmi); + return (ret); +} + + +/* + * Check if the given GUID string (human readable format AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP) + * exists within _WDG + */ +static int +acpi_wmi_provides_guid_string_method(device_t dev, const char *guid_string) +{ + int ret; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + ACPI_SERIAL_BEGIN(acpi_wmi); + ret = (acpi_wmi_lookup_wmi_info_by_guid_string(guid_string) == NULL)?0:1; + ACPI_SERIAL_END(acpi_wmi); + return (ret); +} + +/* + * Call a method "method_id" on the given GUID block + * write result into user provided output buffer + */ +static ACPI_STATUS +acpi_wmi_evaluate_call_method(device_t dev, const char *guid_string, UINT8 instance, + UINT32 method_id, const ACPI_BUFFER *in, ACPI_BUFFER *out) +{ + ACPI_OBJECT params[3]; + ACPI_OBJECT_LIST input; + char method[5] = "WMxx"; + struct wmi_info *winfo; + struct acpi_wmi_softc *sc; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + ACPI_SERIAL_BEGIN(acpi_wmi); + if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) == NULL) + status = AE_NOT_FOUND; + else if (!(winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) + status = AE_BAD_DATA; + else if (instance > winfo->ginfo.max_instance) + status = AE_BAD_PARAMETER; + else { + params[0].Type = ACPI_TYPE_INTEGER; + params[0].Integer.Value = instance; + params[1].Type = ACPI_TYPE_INTEGER; + params[1].Integer.Value = method_id; + input.Pointer = params; + input.Count = 2; + if (in) { + params[2].Type = (winfo->ginfo.flags & ACPI_WMI_REGFLAG_STRING) + ?ACPI_TYPE_STRING:ACPI_TYPE_BUFFER; + params[2].Buffer.Length = in->Length; + params[2].Buffer.Pointer = in->Pointer; + input.Count = 3; + } + method[2] = winfo->ginfo.oid[0]; + method[3] = winfo->ginfo.oid[1]; + status = AcpiEvaluateObject(sc->wmi_handle, method, &input, out); + } + ACPI_SERIAL_END(acpi_wmi); + return (status); +} + +/* + * Install a user provided event_handler on the given GUID + * provided *data will be passed on callback + * If there is already an existing event handler registered it will be silently discarded + */ +static ACPI_STATUS +acpi_wmi_install_event_handler_method(device_t dev, const char *guid_string, + ACPI_NOTIFY_HANDLER event_handler, void *data) +{ + struct wmi_info *winfo; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + status = AE_OK; + ACPI_SERIAL_BEGIN(acpi_wmi); + if (guid_string == NULL || event_handler == NULL) + status = AE_BAD_PARAMETER; + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) == NULL) + status = AE_NOT_EXIST; + else if (winfo->event_handler != NULL || + (status = acpi_wmi_toggle_we_event_generation(dev, winfo, EVENT_GENERATION_ON)) == AE_OK) { + winfo->event_handler = event_handler; + winfo->event_handler_user_data = data; + } + ACPI_SERIAL_END(acpi_wmi); + return (status); +} + +/* + * Remove a previously installed event handler from the given GUID + * If there was none installed, this call is silently discarded and reported as AE_OK + */ +static ACPI_STATUS +acpi_wmi_remove_event_handler_method(device_t dev, const char *guid_string) +{ + struct wmi_info *winfo; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + status = AE_OK; + ACPI_SERIAL_BEGIN(acpi_wmi); + if (guid_string && + (winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) != NULL && + winfo->event_handler) + { + status = acpi_wmi_toggle_we_event_generation(dev, winfo, EVENT_GENERATION_OFF); + winfo->event_handler = NULL; + winfo->event_handler_user_data = NULL; + } + ACPI_SERIAL_END(acpi_wmi); + return (status); +} + +/* + * Get details on an event received through a callback registered + * through ACPI_WMI_REMOVE_EVENT_HANDLER into a user provided output buffer. + * (event_id equals "notify" passed in the callback) + */ +static ACPI_STATUS +acpi_wmi_get_event_data_method(device_t dev, UINT32 event_id, ACPI_BUFFER *out) +{ + ACPI_OBJECT_LIST input; + ACPI_OBJECT params[1]; + struct acpi_wmi_softc *sc; + struct wmi_info *winfo; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + status = AE_NOT_FOUND; + ACPI_SERIAL_BEGIN(acpi_wmi); + params[0].Type = ACPI_TYPE_INTEGER; + params[0].Integer.Value = event_id; + input.Pointer = params; + input.Count = 1; + TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) && + ((UINT8) winfo->ginfo.oid[0] == event_id)) { + status = AcpiEvaluateObject(sc->wmi_handle, "_WED", &input, out); + break; + } + } + ACPI_SERIAL_END(acpi_wmi); + return (status); +} + +/* + * Read a block of data from the given GUID (using WQxx (query)) + * Will be returned in a user provided buffer (out). + * If the method is marked as expensive (ACPI_WMI_REGFLAG_EXPENSIVE) + * we will first call the WCxx control method to lock the node to + * lock the node for data collection and release it afterwards. + * (Failed WCxx calls are ignored to "support" broken implementations) + */ +static ACPI_STATUS +acpi_wmi_get_block_method(device_t dev, const char *guid_string, UINT8 instance, + ACPI_BUFFER *out) +{ + char wc_method[5] = "WCxx"; + char wq_method[5] = "WQxx"; + ACPI_OBJECT_LIST wc_input; + ACPI_OBJECT_LIST wq_input; + ACPI_OBJECT wc_params[1]; + ACPI_OBJECT wq_params[1]; + ACPI_HANDLE wc_handle; + struct acpi_wmi_softc *sc; + struct wmi_info *winfo; + ACPI_STATUS status; + ACPI_STATUS wc_status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + wc_status = AE_ERROR; + ACPI_SERIAL_BEGIN(acpi_wmi); + if (guid_string == NULL || out == NULL) + status = AE_BAD_PARAMETER; + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) == NULL) + status = AE_ERROR; + else if (instance > winfo->ginfo.max_instance) + status = AE_BAD_PARAMETER; + else if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) || + (winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) + status = AE_ERROR; + else { + wq_params[0].Type = ACPI_TYPE_INTEGER; + wq_params[0].Integer.Value = instance; + wq_input.Pointer = wq_params; + wq_input.Count = 1; + if (winfo->ginfo.flags & ACPI_WMI_REGFLAG_EXPENSIVE) { + wc_params[0].Type = ACPI_TYPE_INTEGER; + wc_params[0].Integer.Value = 1; + wc_input.Pointer = wc_params; + wc_input.Count = 1; + wc_method[2] = winfo->ginfo.oid[0]; + wc_method[3] = winfo->ginfo.oid[1]; + wc_status = AcpiGetHandle(sc->wmi_handle, wc_method, &wc_handle); + if (ACPI_SUCCESS(wc_status)) + wc_status = AcpiEvaluateObject(wc_handle, wc_method, &wc_input, NULL); + } + wq_method[2] = winfo->ginfo.oid[0]; + wq_method[3] = winfo->ginfo.oid[1]; + status = AcpiEvaluateObject(sc->wmi_handle, wq_method, &wq_input, out); + if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { + wc_params[0].Integer.Value = 0; + status = AcpiEvaluateObject(wc_handle, wc_method, &wc_input, NULL); /* XXX this might be the wrong status to return? */ + } + } + ACPI_SERIAL_END(acpi_wmi); + return (status); +} + +/* + * Write a block of data to the given GUID (using WSxx) + */ +static ACPI_STATUS +acpi_wmi_set_block_method(device_t dev, const char *guid_string, UINT8 instance, + const ACPI_BUFFER *in) +{ + char method[5] = "WSxx"; + ACPI_OBJECT_LIST input; + ACPI_OBJECT params[2]; + struct wmi_info *winfo; + struct acpi_wmi_softc *sc; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + ACPI_SERIAL_BEGIN(acpi_wmi); + if (guid_string == NULL || in == NULL) + status = AE_BAD_DATA; + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + == NULL) + status = AE_ERROR; + else if (instance > winfo->ginfo.max_instance) + status = AE_BAD_PARAMETER; + else if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) || + (winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) + status = AE_ERROR; + else { + params[0].Type = ACPI_TYPE_INTEGER; + params[0].Integer.Value = instance; + input.Pointer = params; + input.Count = 2; + params[1].Type = (winfo->ginfo.flags & ACPI_WMI_REGFLAG_STRING) + ?ACPI_TYPE_STRING:ACPI_TYPE_BUFFER; + params[1].Buffer.Length = in->Length; + params[1].Buffer.Pointer = in->Pointer; + method[2] = winfo->ginfo.oid[0]; + method[3] = winfo->ginfo.oid[1]; + status = AcpiEvaluateObject(sc->wmi_handle, method, &input, NULL); + } + ACPI_SERIAL_END(acpi_wmi); + return (status); +} + +/* + * Handle events received and dispatch them to + * stakeholders that registered through ACPI_WMI_INSTALL_EVENT_HANDLER + */ +static void +acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) +{ + ACPI_NOTIFY_HANDLER handler; + void *handler_data; + struct wmi_info *winfo; + + ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); + + handler = NULL; + handler_data = NULL; + ACPI_SERIAL_BEGIN(acpi_wmi); + TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) && + ((UINT8) winfo->ginfo.oid[0] == notify)) { + if (winfo->event_handler) { + handler = winfo->event_handler; + handler_data = winfo->event_handler_user_data; + break; + } + } + } + ACPI_SERIAL_END(acpi_wmi); + if (handler) { + handler(h, notify, handler_data); + } +} + +/* + * Handle EC address space notifications reveived on the WDG node + * (this mimics EcAddressSpaceHandler in acpi_ec.c) + */ +static ACPI_STATUS +acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, UINT32 width, + ACPI_INTEGER *value, void *context, void *region_context) +{ + struct acpi_wmi_softc *sc; + int i; + ACPI_INTEGER ec_data; + UINT8 ec_addr; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Address); + + sc = (struct acpi_wmi_softc *)context; + if (width % 8 != 0 || value == NULL || context == NULL) + return (AE_BAD_PARAMETER); + if (address + (width / 8) - 1 > 0xFF) + return (AE_BAD_ADDRESS); + if (function == ACPI_READ) + *value = 0; + ec_addr = address; + status = AE_ERROR; + + for (i = 0; i < width; i += 8, ++ec_addr) { + switch (function) { + case ACPI_READ: + status = ACPI_EC_READ(sc->ec_dev, ec_addr, &ec_data, 1); + if (ACPI_SUCCESS(status)) + *value |= ((ACPI_INTEGER)ec_data) << i; + break; + case ACPI_WRITE: + ec_data = (UINT8)((*value) >> i); + status = ACPI_EC_WRITE(sc->ec_dev, ec_addr, ec_data, 1); + break; + default: + device_printf(sc->wmi_dev, "invalid acpi_wmi_ec_handler function %d\n", + function); + status = AE_BAD_PARAMETER; + break; + } + if (ACPI_FAILURE(status)) + break; + } + return (status); +} + +/* + * Read GUID blocks from the _WDG node + * into wmi_info_list. + */ +static ACPI_STATUS +acpi_wmi_read_wdg_blocks(ACPI_HANDLE h) +{ + ACPI_BUFFER out = {ACPI_ALLOCATE_BUFFER, NULL}; + struct guid_info *ginfo; + ACPI_OBJECT *obj; + struct wmi_info *winfo; + UINT32 i; + UINT32 wdg_block_count; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + ACPI_SERIAL_ASSERT(acpi_wmi); + if (ACPI_FAILURE(status = AcpiEvaluateObject(h, "_WDG", NULL, &out))) + return (status); + obj = (ACPI_OBJECT*) out.Pointer; + wdg_block_count = obj->Buffer.Length / sizeof(struct guid_info); + if ((ginfo = malloc(obj->Buffer.Length, M_ACPIWMI, M_NOWAIT)) == NULL) { + AcpiOsFree(out.Pointer); + return (AE_NO_MEMORY); + } + memcpy(ginfo, obj->Buffer.Pointer, obj->Buffer.Length); + for (i = 0; i < wdg_block_count; ++i) { + if ((winfo = malloc(sizeof(struct wmi_info), M_ACPIWMI, M_NOWAIT | M_ZERO)) == NULL) { + AcpiOsFree(out.Pointer); + free(ginfo, M_ACPIWMI); + return (AE_NO_MEMORY); + } + winfo->ginfo = ginfo[i]; + TAILQ_INSERT_TAIL(&wmi_info_list, winfo, wmi_list); + } + AcpiOsFree(out.Pointer); + free(ginfo, M_ACPIWMI); + return (status); +} + +/* + * Toggle event generation in for the given GUID (passed by winfo) + * Turn on to get notified (through acpi_wmi_notify_handler) if eventy happen + * on the given GUID. + */ +static ACPI_STATUS +acpi_wmi_toggle_we_event_generation(device_t dev, struct wmi_info *winfo, enum event_generation_state state) +{ + char method[5] = "WExx"; + ACPI_OBJECT_LIST input; + ACPI_OBJECT params[1]; + struct acpi_wmi_softc *sc; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + ACPI_SERIAL_ASSERT(acpi_wmi); + params[0].Type = ACPI_TYPE_INTEGER; + params[0].Integer.Value = state==EVENT_GENERATION_ON?1:0; + input.Pointer = params; + input.Count = 1; + + UINT8 hi = ((UINT8) winfo->ginfo.oid[0]) >> 4; + UINT8 lo = ((UINT8) winfo->ginfo.oid[0]) & 0xf; + method[2] = (hi > 9 ? hi + 55: hi + 48); + method[3] = (lo > 9 ? lo + 55: lo + 48); + status = AcpiEvaluateObject(sc->wmi_handle, method, &input, NULL); + if (status == AE_NOT_FOUND) status = AE_OK; + return (status); +} + +/* + * Convert given two digit hex string (hexin) to an UINT8 referenced + * by byteout. + * Return != 0 if the was a problem (invalid input) + */ +static __inline int acpi_wmi_hex_to_int(const UINT8 *hexin, UINT8 *byteout) +{ + unsigned int hi; + unsigned int lo; + + hi = hexin[0]; + lo = hexin[1]; + if ('0' <= hi && hi <= '9') + hi -= '0'; + else if ('A' <= hi && hi <= 'F') + hi -= ('A' - 10); + else if ('a' <= hi && hi <= 'f') + hi -= ('a' - 10); + else + return (1); + if ('0' <= lo && lo <= '9') + lo -= '0'; + else if ('A' <= lo && lo <= 'F') + lo -= ('A' - 10); + else if ('a' <= lo && lo <= 'f') + lo -= ('a' - 10); + else + return (1); + *byteout = (hi << 4) + lo; + return (0); +} + +/* + * Convert a human readable 36 character GUID into a 16byte machine readable one. + * The basic algorithm looks as follows: + * Input: AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP + * Output: DCBAFEHGIJKLMNOP + * (AA BB CC etc. represent two digit hex numbers == bytes) + * Return != 0 if passed guid string is invalid + */ +static int +acpi_wmi_guid_string_to_guid(const UINT8 *guid_string, UINT8 *guid) +{ + static const int mapping[20] = {3, 2, 1, 0, -1, 5, 4, -1, 7, 6, -1, 8, 9, + -1, 10, 11, 12, 13, 14, 15}; + int i; + + for (i = 0; i < 20; ++i, ++guid_string) { + if (mapping[i] >= 0) { + if (acpi_wmi_hex_to_int(guid_string, &guid[mapping[i]])) + return (-1); + ++guid_string; + } else if (*guid_string != '-') + return (-1); + } + return (0); +} + +/* + * Lookup a wmi_info structure in wmi_list based on a + * human readable GUID + * Return NULL if the GUID is unknown in the _WDG + */ +static struct wmi_info* +acpi_wmi_lookup_wmi_info_by_guid_string(const char *guid_string) +{ + char guid[16]; + struct wmi_info *winfo; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + ACPI_SERIAL_ASSERT(acpi_wmi); + + if (!acpi_wmi_guid_string_to_guid(guid_string, guid)) { + TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + if (!memcmp(winfo->ginfo.guid, guid, 16)) { + return (winfo); + } + } + } + return (NULL); +} + +/* + * open wmistat device + */ +static int +acpi_wmi_wmistat_open(struct cdev* dev, int flags, int mode, struct thread *td) +{ + struct acpi_wmi_softc *sc; + int ret; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(acpi_wmi); + if (sc->wmistat_open_pid != 0) { + ret = EBUSY; + } + else { + if (sbuf_new(&sc->wmistat_sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) { + ret = ENXIO; + } else { + sc->wmistat_open_pid = td->td_proc->p_pid; + sc->wmistat_bufptr = 0; + ret = 0; + } + } + ACPI_SERIAL_END(acpi_wmi); + return (ret); +} + +/* + * close wmistat device + */ +static int +acpi_wmi_wmistat_close(struct cdev* dev, int flags, int mode, struct thread *td) +{ + struct acpi_wmi_softc *sc; + int ret; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(acpi_wmi); + if (sc->wmistat_open_pid == 0) { + ret = EBADF; + } + else { + if (sc->wmistat_bufptr != -1) { + sbuf_delete(&sc->wmistat_sbuf); + sc->wmistat_bufptr = -1; + } + sc->wmistat_open_pid = 0; + ret = 0; + } + ACPI_SERIAL_END(acpi_wmi); + return (ret); +} + +/* + * Read from wmistat guid information + */ +static int +acpi_wmi_wmistat_read(struct cdev *dev, struct uio *buf, int flag) +{ + struct acpi_wmi_softc *sc; + struct wmi_info *winfo; + int l; + int ret; + UINT8* guid; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(acpi_wmi); + if (sc->wmistat_open_pid != buf->uio_td->td_proc->p_pid || + sc->wmistat_bufptr == -1) { + ret = EBADF; + } + else { + if (!sbuf_done(&sc->wmistat_sbuf)) { + sbuf_printf(&sc->wmistat_sbuf, "GUID INST EXPE METH STR EVENT OID\n"); + TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + guid = (UINT8*)winfo->ginfo.guid; + sbuf_printf(&sc->wmistat_sbuf, + "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X} %3d %-5s", + guid[3], guid[2], guid[1], guid[0], + guid[5], guid[4], + guid[7], guid[6], + guid[8], guid[9], + guid[10], guid[11], guid[12], guid[13], guid[14], guid[15], + winfo->ginfo.max_instance, + (winfo->ginfo.flags&ACPI_WMI_REGFLAG_EXPENSIVE)?"YES":"NO" + ); + if (winfo->ginfo.flags&ACPI_WMI_REGFLAG_METHOD) + sbuf_printf(&sc->wmistat_sbuf, "WM%c%c ", + winfo->ginfo.oid[0], winfo->ginfo.oid[1]); + else + sbuf_printf(&sc->wmistat_sbuf, "NO "); + sbuf_printf(&sc->wmistat_sbuf, "%-4s", + (winfo->ginfo.flags&ACPI_WMI_REGFLAG_STRING)?"YES":"NO" + ); + if (winfo->ginfo.flags&ACPI_WMI_REGFLAG_EVENT) + sbuf_printf(&sc->wmistat_sbuf, "0x%02X%s -\n", + (UINT8)winfo->ginfo.oid[0], winfo->event_handler==NULL?" ":"+"); + else + sbuf_printf(&sc->wmistat_sbuf, "NO %c%c\n", + winfo->ginfo.oid[0], winfo->ginfo.oid[1]); + } + sbuf_finish(&sc->wmistat_sbuf); + } + if (sbuf_len(&sc->wmistat_sbuf) <= 0) { + sbuf_delete(&sc->wmistat_sbuf); + sc->wmistat_bufptr = -1; + sc->wmistat_open_pid = 0; + ret = ENOMEM; + } else { + l = min(buf->uio_resid, sbuf_len(&sc->wmistat_sbuf) - sc->wmistat_bufptr); + ret = (l > 0)?uiomove(sbuf_data(&sc->wmistat_sbuf) + sc->wmistat_bufptr, l, buf) : 0; + sc->wmistat_bufptr += l; + } + } + ACPI_SERIAL_END(acpi_wmi); + return (ret); +} --- sys/dev/acpi_support/acpi_wmi_if.m~ 2009-06-21 12:09:58.000000000 +0200 +++ sys/dev/acpi_support/acpi_wmi_if.m 2009-06-21 12:13:23.546375847 +0200 @@ -0,0 +1,144 @@ +#- +# Copyright (c) 2009 Michael Gmelin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD: src/sys/dev/acpic_support/acpi_wmi_if.m,v 1.0 2008/11/23 16:33:00 rmg Exp $ +# + +#include +#include +#include + +INTERFACE acpi_wmi; + +# +# Default implementation for acpi_wmi_generic_provides_guid_string(). +# +CODE { + static int + acpi_wmi_generic_provides_guid_string(device_t dev, const char* guid_string) + { + return 0; + } +}; + + +# +# Check if given GUID exists in WMI +# +# device_t dev: Device to probe +# const char* guid_string: String form of the GUID +# +METHOD int provides_guid_string { + device_t dev; + const char* guid_string; +} DEFAULT acpi_wmi_generic_provides_guid_string; + +# +# Evaluate a WMI method call +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# UINT8 instance: instance id +# UINT32 method_id: method to call +# const ACPI_BUFFER* in: input data +# ACPI_BUFFER* out: output buffer +# +METHOD ACPI_STATUS evaluate_call { + device_t dev; + const char *guid_string; + UINT8 instance; + UINT32 method_id; + const ACPI_BUFFER *in; + ACPI_BUFFER *out; +}; + +# +# Get content of a WMI block +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# UINT8 instance: instance id +# ACPI_BUFFER* out: output buffer +# +METHOD ACPI_STATUS get_block { + device_t dev; + const char *guid_string; + UINT8 instance; + ACPI_BUFFER *out; +}; +# +# Write to a WMI data block +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# UINT8 instance: instance id +# const ACPI_BUFFER* in: input data +# +METHOD ACPI_STATUS set_block { + device_t dev; + const char *guid_string; + UINT8 instance; + const ACPI_BUFFER *in; +}; + +# +# Install wmi event handler +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# ACPI_NOTIFY_HANDLER handler: Handler +# void* data: Payload +# +METHOD ACPI_STATUS install_event_handler { + device_t dev; + const char *guid_string; + ACPI_NOTIFY_HANDLER handler; + void *data; +}; + +# +# Remove wmi event handler +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# +METHOD ACPI_STATUS remove_event_handler { + device_t dev; + const char *guid_string; +}; + + +# +# Get event data associated to an event +# +# device_t dev: Device to use +# UINT32 event_id: event id +# ACPI_BUFFER* out: output buffer +# +METHOD ACPI_STATUS get_event_data { + device_t dev; + UINT32 event_id; + ACPI_BUFFER *out; +}; --- sys/modules/acpi/acpi_hp/Makefile~ 2009-06-21 12:09:58.000000000 +0200 +++ sys/modules/acpi/acpi_hp/Makefile 2009-06-21 12:10:33.000000000 +0100 @@ -0,0 +1,9 @@ +# $FreeBSD: src/sys/modules/acpi/acpi_hp/Makefile,v 1.3 2004/12/13 04:59:35 imp Exp $ + +.PATH: ${.CURDIR}/../../../dev/acpi_support +KMOD= acpi_hp +CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica +SRCS= acpi_hp.c opt_acpi.h device_if.h bus_if.h acpi_if.h acpi_wmi_if.h +SRCS+= opt_ddb.h + +.include --- sys/modules/acpi/acpi_wmi/Makefile~ 2009-06-21 12:09:58.000000000 +0200 +++ sys/modules/acpi/acpi_wmi/Makefile 2009-06-21 12:10:39.000000000 +0100 @@ -0,0 +1,10 @@ +# $FreeBSD: src/sys/modules/acpi/acpi_wmi/Makefile,v 1.7 2007/06/24 20:36:51 njl Exp $ + +.PATH: ${.CURDIR}/../../../dev/acpi_support + +KMOD= acpi_wmi +CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica +SRCS= acpi_wmi.c +SRCS+= opt_acpi.h acpi_if.h bus_if.h device_if.h acpi_wmi_if.h + +.include --- sys/conf/files.i386~ 2008-12-29 04:46:14.000000000 +0100 +++ sys/conf/files.i386 2009-06-21 12:10:14.000000000 +0100 @@ -226,6 +226,7 @@ dev/syscons/scvtb.c optional sc dev/uart/uart_cpu_i386.c optional uart dev/acpica/acpi_if.m standard +dev/acpi_support/acpi_wmi_if.m standard dev/wpi/if_wpi.c optional wpi i386/acpica/OsdEnvironment.c optional acpi i386/acpica/acpi_machdep.c optional acpi --- sys/conf/files~ 2008-12-29 04:45:44.000000000 +0100 +++ sys/conf/files 2009-06-21 12:10:44.000000000 +0100 @@ -375,9 +375,11 @@ dev/aac/aac_disk.c optional aac dev/aac/aac_linux.c optional aac compat_linux dev/aac/aac_pci.c optional aac pci +dev/acpi_support/acpi_wmi.c optional acpi_wmi acpi dev/acpi_support/acpi_aiboost.c optional acpi_aiboost acpi dev/acpi_support/acpi_asus.c optional acpi_asus acpi dev/acpi_support/acpi_fujitsu.c optional acpi_fujitsu acpi +dev/acpi_support/acpi_hp.c optional acpi_hp acpi dev/acpi_support/acpi_ibm.c optional acpi_ibm acpi dev/acpi_support/acpi_panasonic.c optional acpi_panasonic acpi dev/acpi_support/acpi_sony.c optional acpi_sony acpi --- sys/conf/kmod.mk~ 2008-12-29 04:44:41.000000000 +0100 +++ sys/conf/kmod.mk 2009-06-21 12:10:41.000000000 +0100 @@ -321,7 +321,7 @@ .endfor .endif -MFILES?= dev/acpica/acpi_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \ +MFILES?= dev/acpica/acpi_if.m dev/acpi_support/acpi_wmi_if.m dev/agp/agp_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \ dev/iicbus/iicbb_if.m dev/iicbus/iicbus_if.m \ dev/mmc/mmcbr_if.m dev/mmc/mmcbus_if.m \ dev/mii/miibus_if.m dev/ofw/ofw_bus_if.m \ --- share/man/man4/man4.i386/Makefile~ 2009-06-21 12:36:50.000000000 +0200 +++ share/man/man4/man4.i386/Makefile 2009-06-21 12:36:50.000000000 +0200 @@ -3,10 +3,12 @@ MAN= acpi_aiboost.4 \ acpi_asus.4 \ acpi_fujitsu.4 \ + acpi_hp.4 \ acpi_ibm.4 \ acpi_panasonic.4 \ acpi_sony.4 \ acpi_toshiba.4 \ + acpi_wmi.4 \ aic.4 \ alpm.4 \ amdpm.4 \ --------------000106060507010904000207 Content-Type: application/octet-stream; name="patches.tgz" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="patches.tgz" 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 Xp6X5+V5eV6el+fleXlenv+bnv8fEDd+cACQAQA= --------------000106060507010904000207-- From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 11:59:03 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 444F51065670 for ; Sun, 21 Jun 2009 11:59:03 +0000 (UTC) (envelope-from naylor.b.david@gmail.com) Received: from mail-ew0-f212.google.com (mail-ew0-f212.google.com [209.85.219.212]) by mx1.freebsd.org (Postfix) with ESMTP id 9A8958FC15 for ; Sun, 21 Jun 2009 11:59:02 +0000 (UTC) (envelope-from naylor.b.david@gmail.com) Received: by ewy8 with SMTP id 8so3111099ewy.43 for ; Sun, 21 Jun 2009 04:59:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:organization:to:subject :date:user-agent:cc:references:in-reply-to:mime-version:content-type :content-transfer-encoding:message-id; bh=KUMJgnMdeZ9NtGxyOfnwcdrc+hV9Kgfzw91y9osgx/Y=; b=E87SGEh/hmYGB8Ndg5SbQUDQuZehcRms9MInzP6xUx0xmu+OZNnF7oSjltUoOU1eQH sc7o1puMUHrWtt9KB6pYPsX6Y3RGEqaHhQywUgAD80Il5uAO0BBLNaKC9OB03nROdKlE 2NMAgJCP6NtjTd3Kdbzn6pA6fwxwKF0BF/xJk= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:organization:to:subject:date:user-agent:cc:references :in-reply-to:mime-version:content-type:content-transfer-encoding :message-id; b=adLnRvwGDEMhVoomd+dVYtAdCl2tT2albZMZN+sNmv+JD93hkD0pLky8GSWdMKp8c0 KY83SnorBGA9GIsyXqassFQOg/R2ezQElj220skr+lHBYmPCK15YN8yA9FMNkb0XdSVX EJQaI3WSyTAtiU1vtFfVfePtvz/WbyiPOc2u4= Received: by 10.210.37.16 with SMTP id k16mr5834200ebk.5.1245585541600; Sun, 21 Jun 2009 04:59:01 -0700 (PDT) Received: from dragonmini.dg ([196.34.241.123]) by mx.google.com with ESMTPS id 10sm76111eyd.7.2009.06.21.04.58.58 (version=SSLv3 cipher=RC4-MD5); Sun, 21 Jun 2009 04:59:00 -0700 (PDT) From: David Naylor Organization: Private To: Peter Harrison Date: Sun, 21 Jun 2009 14:00:14 +0200 User-Agent: KMail/1.9.10 References: <200906181407.11607.naylor.b.david@gmail.com> <200906182100.15817.naylor.b.david@gmail.com> <20090620130403.GA1051@ideapad.piggybox> In-Reply-To: <20090620130403.GA1051@ideapad.piggybox> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart2794496.uAsAAFD5zS"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit Message-Id: <200906211400.19033.naylor.b.david@gmail.com> X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: freebsd-acpi@freebsd.org Subject: Re: [PATCH] Lenovo S10(e) ACPI X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 11:59:03 -0000 --nextPart2794496.uAsAAFD5zS Content-Type: multipart/mixed; boundary="Boundary-01=_PDiPKHdYgyMEI2V" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_PDiPKHdYgyMEI2V Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Saturday 20 June 2009 15:04:03 Peter Harrison wrote: > Thursday, 18 June 2009 at 21:00:11 +0200, David Naylor said: > > On Thursday 18 June 2009 19:40:28 Peter Harrison wrote: > > > Thursday, 18 June 2009 at 14:07:07 +0200, David Naylor said: > > > > Hi, > > > > > > > > ((Short version: apply patch and add 'debug.acpi.ec.gpe=3D1' > > > > and 'debug.acpi.ec.timeout=3D100' to loader.conf and EC (battery, > > > > thermal) ?should? work)) > > > > > > > > P.S. If this doesn't work please include details (and dmesg output) > > > > and I'll try to help. > > David, > > The patch applied cleanly, and I've rebuilt and installed. System seems to > work fine and I'm getting battery time reported properly. It still won't > poweroff on shutdown though... > > uname -a: > FreeBSD ideapad.piggybox 7.2-RELEASE-p1 FreeBSD 7.2-RELEASE-p1 #0: Sat Jun > 20 11:03:21 BST 2009 =20 > peter@ideapad.piggybox:/usr/obj/usr/src/sys/GENERIC i386 > > dmesg: I can't see anything that shouts out as being wrong, EC attaches correctly = and=20 no timeout errors. =20 Please see attached for a new patch, it fixes a potential (but unlikely) ra= ce=20 condition that could freeze the EC. It also 'fixes' the timeout problem=20 (well, the workaround seems more stable). =20 This adds another tunable/sysctl called ``debug.acpi.ec.delay''. It defaul= ts=20 to 0 (no change) but when set to a value it adds a delay (in microseconds)= =20 after each successful request. This delay (at about ~200) appears to fix t= he=20 problem. I'll still recommend having debug.acpi.ec.gpe and=20 debug.acpi.ec.timeout set (just in case). So you should have in loader.con= f: debug.acpi.ec.delay=3D"200" # (us) debug.acpi.ec.gpe=3D"1" # Optional but recommended debug.acpi.ec.timeout=3D"100" # (ms) Optional but recommended If you are getting some `wait timeout' messages you can try increasing=20 debug.acpi.ec.delay. =20 I'm not sure what is stopping your computer from shutting down (have you tr= ied=20 `halt -p`?). The only difference that I can spot if that I'm using -curren= t=20 (with the new acpi code). The patch may work, otherwise you could=20 give -current a try (it is probably easy enough to backport the ACPI=20 import...). =20 Regards, David --Boundary-01=_PDiPKHdYgyMEI2V-- --nextPart2794496.uAsAAFD5zS Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (FreeBSD) iEYEABECAAYFAko+INIACgkQUaaFgP9pFrKLEwCfW57pE273s5JE4UR7YFdjAgql i/8An2wTrxBOIEaUJMyZhEFLAPVLueSG =mjdS -----END PGP SIGNATURE----- --nextPart2794496.uAsAAFD5zS-- From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 13:56:06 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6445F1065674 for ; Sun, 21 Jun 2009 13:56:06 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: from mail-ew0-f212.google.com (mail-ew0-f212.google.com [209.85.219.212]) by mx1.freebsd.org (Postfix) with ESMTP id C00FD8FC13 for ; Sun, 21 Jun 2009 13:56:05 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: by ewy8 with SMTP id 8so3152495ewy.43 for ; Sun, 21 Jun 2009 06:56:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:message-id:from:to :content-type:content-transfer-encoding:mime-version:subject:date:cc :x-mailer; bh=TGS9OngGrDV0aKAgpjUysxQHepprdYwZF3FOtstMq6o=; b=QpSWCnKyv01ZZ7j2p6dmsRKOU6QNTikygMZg4Oh++YoedDUddRh4nJnz8Q9p3gKGMa w6AgYF5h1zUehGXG+PuIxVW470T5LEowurOMDI4TWKYsNlhigJMD1g1GVeCd5f/Bbj5y GA7hzl9NSHKqJlIAgNSFN65b1Nnas7BDNCLz8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:message-id:from:to:content-type:content-transfer-encoding :mime-version:subject:date:cc:x-mailer; b=tkvW4/8o6AlsTGZ9ElGEnurXi6fM3ru4SieL7tqQpzRLQXCdccz6fY7fyu1nZRqDzQ zZ9MF1OjDnqsOLPoYdCS1WqusO2JjGH0+CYDIYrF/gpNJstYCoSLBB+jiq7KEF96nwbT yJTMykgIvf42M5mj4B+udxvAqK/lU6s4AxZ20= Received: by 10.210.12.18 with SMTP id 18mr3375226ebl.87.1245592564717; Sun, 21 Jun 2009 06:56:04 -0700 (PDT) Received: from omega.lan (bl9-155-202.dsl.telepac.pt [85.242.155.202]) by mx.google.com with ESMTPS id 5sm3488738eyh.50.2009.06.21.06.56.03 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 21 Jun 2009 06:56:04 -0700 (PDT) Sender: Rui Paulo Message-Id: <2F4DD9CA-934B-4BAB-9550-F9897623741F@freebsd.org> From: Rui Paulo To: freebsd-acpi@freebsd.org Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v935.3) Date: Sun, 21 Jun 2009 14:56:02 +0100 X-Mailer: Apple Mail (2.935.3) Cc: Subject: ACPI regression X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 13:56:07 -0000 Hi, I just found out that 7.2 boots ok on my 2009 Mac mini, but 8.0 doesn't. The reason for this is related to ACPI. I don't have much time available to debug this right now, so this is just sort of a heads up. The machine locks up after printing the acpi0 driver announcement. (Disabling ACPI makes the system boot, but many devices are missing, including the SATA controller -- no install possible). I'll keep you informed if something else comes up. -- Rui Paulo From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 14:05:01 2009 Return-Path: Delivered-To: freebsd-acpi@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 057EB1065673; Sun, 21 Jun 2009 14:05:01 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id CE0B48FC0A; Sun, 21 Jun 2009 14:05:00 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from freefall.freebsd.org (rpaulo@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n5LE502W009243; Sun, 21 Jun 2009 14:05:00 GMT (envelope-from rpaulo@freefall.freebsd.org) Received: (from rpaulo@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n5LE4x7a009233; Sun, 21 Jun 2009 14:04:59 GMT (envelope-from rpaulo) Date: Sun, 21 Jun 2009 14:04:59 GMT Message-Id: <200906211404.n5LE4x7a009233@freefall.freebsd.org> To: funa@funa.org, rpaulo@FreeBSD.org, freebsd-acpi@FreeBSD.org From: rpaulo@FreeBSD.org Cc: Subject: Re: kern/128639: [patch] [acpi_asus] acpi for ASUS A6F, A3E, A3F, A3N not working X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 14:05:01 -0000 Synopsis: [patch] [acpi_asus] acpi for ASUS A6F,A3E,A3F,A3N not working State-Changed-From-To: open->feedback State-Changed-By: rpaulo State-Changed-When: Sun Jun 21 14:04:34 UTC 2009 State-Changed-Why: Can you try a more recent FreeBSD version, please? http://www.freebsd.org/cgi/query-pr.cgi?pr=128639 From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 14:17:49 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 41D7D1065670 for ; Sun, 21 Jun 2009 14:17:49 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: from mail-ew0-f212.google.com (mail-ew0-f212.google.com [209.85.219.212]) by mx1.freebsd.org (Postfix) with ESMTP id BD5B58FC15 for ; Sun, 21 Jun 2009 14:17:48 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: by ewy8 with SMTP id 8so3161748ewy.43 for ; Sun, 21 Jun 2009 07:17:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:cc:message-id:from:to :in-reply-to:content-type:content-transfer-encoding:mime-version :subject:date:references:x-mailer; bh=rVttqbRkA7fr0ILhrtSjKldIUBIr7nBBk+UNczsGhzc=; b=rBuUxJhdqNIFXsfuM9qjMed/jk0x3/IARSaLy3WmmLmwUDxJd8YRugicNXpNDfRJTD kfK97dCsrIhCq9o+rrE31sNRzSvXmAlxTqugjimnEoPE1dEFUDbNq55lD7/7ngxpcrTw fxdt+6z5cpOu06MfMOeyTZw7AHAYJ/Iz9Zcps= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:cc:message-id:from:to:in-reply-to:content-type :content-transfer-encoding:mime-version:subject:date:references :x-mailer; b=I5kNGF1XJcsmgj9Ac6Re+C4sqA2K7W1RD6m1LuoEG36PfUYEs+/gTS81J5hy++pbMe FA+egEe1gIkfRWBfLN41xcc2JrS3+S5Ym5SDQ/JI4a+36nRL3/mn+++f+8J8x03AcTBx /n/tcjioGMtRC1kCQJ0WvX8tV2NrvCPdgavM4= Received: by 10.210.53.5 with SMTP id b5mr3429739eba.79.1245593867848; Sun, 21 Jun 2009 07:17:47 -0700 (PDT) Received: from omega.lan (bl9-155-202.dsl.telepac.pt [85.242.155.202]) by mx.google.com with ESMTPS id 24sm3942503eyx.13.2009.06.21.07.17.47 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 21 Jun 2009 07:17:47 -0700 (PDT) Sender: Rui Paulo Message-Id: From: Rui Paulo To: freebsd-acpi@freebsd.org In-Reply-To: <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v935.3) Date: Sun, 21 Jun 2009 15:17:46 +0100 References: <4A3E1784.2050406@bindone.de> <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> X-Mailer: Apple Mail (2.935.3) Cc: Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 14:17:49 -0000 On 21 Jun 2009, at 15:08, Rui Paulo wrote: > On 21 Jun 2009, at 12:20, Michael wrote: > >> Hello, >> >> I wrote two new acpi modules last year and finally found the time >> to fix >> them, add some missing features and write man pages. > > Michael, this is great work! I'll review and see if we can ship it > with 8.0! Michael, this looks good, but there are two style nits that we need to fix. * we should try not going over the 80 column mark * add a empty new line before every return If you could send me a new patch for 8.0 with these fixes, I'll commit it (unless someone else has objections). Regards, -- Rui Paulo From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 16:27:32 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5BC98106564A for ; Sun, 21 Jun 2009 16:27:32 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 9E16E8FC18 for ; Sun, 21 Jun 2009 16:27:31 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 91182 invoked by uid 89); 21 Jun 2009 16:27:30 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.188.39) by mail.bindone.de with ESMTPA; 21 Jun 2009 16:27:30 -0000 Message-ID: <4A3E5F40.4040709@bindone.de> Date: Sun, 21 Jun 2009 18:26:40 +0200 From: Michael User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: Rui Paulo References: <4A3E1784.2050406@bindone.de> <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 16:27:32 -0000 Rui Paulo wrote: > On 21 Jun 2009, at 15:08, Rui Paulo wrote: > >> On 21 Jun 2009, at 12:20, Michael wrote: >> >>> Hello, >>> >>> I wrote two new acpi modules last year and finally found the time to fix >>> them, add some missing features and write man pages. >> >> Michael, this is great work! I'll review and see if we can ship it >> with 8.0! > > Michael, this looks good, but there are two style nits that we need to fix. > * we should try not going over the 80 column mark > * add a empty new line before every return > > If you could send me a new patch for 8.0 with these fixes, I'll commit > it (unless someone else has objections). > > Regards, > -- > Rui Paulo > Hi Rui, hmm style(9) doesn't say anything about columns or return statements in this context (maybe it should be updated?!?). Anyway, when saying adding an empty line before every return statement, do you also mean conditional return statements: So e.g. int func() { int a; if (!a) return 0; return 1; } Should be: int func() { int a; if (!a) return 0; return 1; } or int func() { int a; if (!a) { return 0; } return 1; } ?? Thanks Michael From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 16:53:46 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 563BC1065680 for ; Sun, 21 Jun 2009 16:53:46 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 2A20A8FC19 for ; Sun, 21 Jun 2009 16:53:41 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 92346 invoked by uid 89); 21 Jun 2009 16:53:40 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.188.39) by mail.bindone.de with ESMTPA; 21 Jun 2009 16:53:40 -0000 Message-ID: <4A3E6563.7040400@bindone.de> Date: Sun, 21 Jun 2009 18:52:51 +0200 From: Michael User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: Rui Paulo References: <4A3E1784.2050406@bindone.de> <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> In-Reply-To: Content-Type: multipart/mixed; boundary="------------000302080806090206000000" Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 16:53:46 -0000 This is a multi-part message in MIME format. --------------000302080806090206000000 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Rui Paulo wrote: > On 21 Jun 2009, at 15:08, Rui Paulo wrote: > >> On 21 Jun 2009, at 12:20, Michael wrote: >> >>> Hello, >>> >>> I wrote two new acpi modules last year and finally found the time to fix >>> them, add some missing features and write man pages. >> >> Michael, this is great work! I'll review and see if we can ship it >> with 8.0! > > Michael, this looks good, but there are two style nits that we need to fix. > * we should try not going over the 80 column mark > * add a empty new line before every return > > If you could send me a new patch for 8.0 with these fixes, I'll commit > it (unless someone else has objections). > > Regards, > -- > Rui Paulo > Hi Rui, I figured that adding newlines in conditional returns makes no sense (see my last post), so I did reformat everything to be (close to) 80 columns a line add added newlines in front of returns at the end of a function. Please find attached the complete patch again (against clean 7.2-RELEASE) and the files that changed (acpi_hp.c and acpi_wmi.c). Btw, what is the normal adoption path for 7-STABLE (I would assume first it gets into HEAD and if there's interest there will be a backport to 7? It should at least work in there, even so for HP laptops my guess is that most users will use 8 anyway because of wireless support). cheers Michael --------------000302080806090206000000 Content-Type: text/plain; name="acpi_wmi_and_acpi_hp_v2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="acpi_wmi_and_acpi_hp_v2.patch" --- sys/i386/conf/NOTES~ 2008-12-29 04:48:16.000000000 +0100 +++ sys/i386/conf/NOTES 2009-06-21 12:10:16.000000000 +0100 @@ -471,6 +471,9 @@ options ACPI_DEBUG #!options ACPI_NO_SEMAPHORES +# ACPI WMI Mapping driver +device acpi_wmi + # ACPI Asus Desktop Extras. (voltage, temp, fan) device acpi_aiboost @@ -480,6 +483,9 @@ # ACPI Fujitsu Extras (Buttons) device acpi_fujitsu +# ACPI extras driver for HP laptops +device acpi_hp + # ACPI extras driver for IBM laptops device acpi_ibm --- sys/modules/acpi/Makefile~ 2008-12-29 04:41:59.000000000 +0100 +++ sys/modules/acpi/Makefile 2009-06-21 12:10:59.000000000 +0100 @@ -4,7 +4,7 @@ SUBDIR= acpi .endif -SUBDIR+= acpi_aiboost acpi_asus acpi_fujitsu acpi_ibm \ +SUBDIR+= acpi_wmi acpi_aiboost acpi_asus acpi_fujitsu acpi_hp acpi_ibm \ acpi_panasonic acpi_sony acpi_toshiba acpi_video \ acpi_dock --- share/man/man4/man4.i386/acpi_hp.4~ 2009-06-21 12:09:58.000000000 +0200 +++ share/man/man4/man4.i386/acpi_hp.4 2009-06-21 12:10:21.229934511 +0200 @@ -0,0 +1,273 @@ +.\" Copyright (c) 2009 Michael Gmelin +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 21, 2009 +.Dt ACPI_HP 4 i386 +.Os +.Sh NAME +.Nm acpi_hp +.Nd "ACPI extras driver for HP laptops" +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following line in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device acpi_hp" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +acpi_hp_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides support for ACPI-controlled features found on HP laptops +that use a WMI enabled BIOS (e.g. HP Compaq 8510p and 6510p). +.Pp +The main purpose of this driver is to provide an interface, +accessible via +.Xr sysctl 8 , +.Xr devd 8 and +.Xr devfs 8 , +through which applications can determine and change the status of +various laptop components and BIOS settings. +.Pp +.Ss Xr devd 8 Ss Events +Devd events received by +.Xr devd 8 +provide the following information: +.Pp +.Bl -tag -width "subsystem" -offset indent -compact +.It system +.Qq Li ACPI +.It subsystem +.Qq Li HP +.It type +The source of the event in the ACPI namespace. +The value depends on the model. +.It notify +Event code (see below). +.El +.Pp +Event codes: +.Pp +.Bl -tag -width "0xc0" -offset indent -compact +.It Li 0xc0 +WLAN on air status changed to 0 (not on air) +.It Li 0xc1 +WLAN on air status changed to 1 (on air) +.It Li 0xd0 +Bluetooth on air status changed to 0 (not on air) +.It Li 0xd1 +Bluetooth on air status changed to 1 (on air) +.It Li 0xe0 +WWAN on air status changed to 0 (not on air) +.It Li 0xe1 +WWAN on air status changed to 1 (on air) +.El +.Ss Xr devfs 8 Ss Device +You can read /dev/hpcmi to see your current BIOS settings. The detail level +can be adjusted by setting the sysctl +.Va cmi_detail +as described below. +.Sh SYSCTL VARIABLES +The following sysctls are currently implemented: +.Ss WLAN: +.Bl -tag -width indent +.It Va dev.acpi_hp.0.wlan_enabled +Toggle WLAN chip activity. +.It Va dev.acpi_hp.0.wlan_radio +(read-only) +WLAN radio status (controlled by hardware switch) +.It Va dev.acpi_hp.0.wlan_on_air +(read-only) +WLAN on air (chip enabled, hardware switch enabled + enabled in BIOS) +.It Va dev.acpi_hp.0.wlan_enabled_if_radio_on +If set to 1, the WLAN chip will be enabled if the radio is turned on +.It Va dev.acpi_hp.0.wlan_disable_if_radio_off +If set to 1, the WLAN chip will be disabled if the radio is turned off +.El +.Ss Bluetooth: +.Bl -tag -width indent +.It Va dev.acpi_hp.0.bt_enabled +Toggle Bluetooth chip activity. +.It Va dev.acpi_hp.0.bt_radio +(read-only) +Bluetooth radio status (controlled by hardware switch) +.It Va dev.acpi_hp.0.bt_on_air +(read-only) +Bluetooth on air (chip enabled, hardware switch enabled + enabled in BIOS) +.It Va dev.acpi_hp.0.bt_enabled_if_radio_on +If set to 1, the Bluetooth chip will be enabled if the radio is turned on +.It Va dev.acpi_hp.0.bt_disable_if_radio_off +If set to 1, the Bluetooth chip will be disabled if the radio is turned off +.El +.Ss WWAN: +.Bl -tag -width indent +.It Va dev.acpi_hp.0.wwan_enabled +Toggle WWAN chip activity. +.It Va dev.acpi_hp.0.wwan_radio +(read-only) +WWAN radio status (controlled by hardware switch) +.It Va dev.acpi_hp.0.wwan_on_air +(read-only) +WWAN on air (chip enabled, hardware switch enabled + enabled in BIOS) +.It Va dev.acpi_hp.0.wwan_enabled_if_radio_on +If set to 1, the WWAN chip will be enabled if the radio is turned on +.It Va dev.acpi_hp.0.wwan_disable_if_radio_off +If set to 1, the WWAN chip will be disabled if the radio is turned off +.El +.Ss Misc: +.Bl -tag -width indent +.It Va dev.acpi_hp.0.als_enabled +Toggle ambient light sensor (ALS) +.It Va dev.acpi_hp.0.display +(read-only) +Display status (bitmask) +.It Va dev.acpi_hp.0.hdd_temperature +(read-only) +HDD temperature +.It Va dev.acpi_hp.0.is_docked +(read-only) +Docking station status (1 if docked) +.It Va dev.acpi_hp.0.cmi_detail +Bitmask to control detail level in /dev/hpcmi output (values can be ORed). +.Bl -tag -width "0x01" -offset indent -compact +.It Li 0x01 +Show path component of BIOS setting +.It Li 0x02 +Show a list of valid options for the BIOS setting +.It Li 0x04 +Show additional flags of BIOS setting (ReadOnly etc.) +.El +.El +.Pp +Defaults for these sysctls can be set in +.Xr sysctl.conf 5 . +.Sh FILES +.Bl -tag -width ".Pa /dev/hpcmi" +.It Pa /dev/hpcmi +Interface to read BIOS settings +.El +.Sh EXAMPLES +The following can be added to +.Xr devd.conf 5 +in order disable the LAN interface when WLAN on air and reenable if it's +not: +.Bd -literal -offset indent +notify 0 { + match "system" "ACPI"; + match "subsystem" "HP"; + match "notify" "0xc0"; + action "ifconfig em0 up"; +}; + +notify 0 { + match "system" "ACPI"; + match "subsystem" "HP"; + match "notify" "0xc1"; + action "ifconfig em0 down"; +}; +.Ed +.Pp +Enable the ambient light sensor: +.Bd -literal -offset indent +sysctl dev.acpi_hp.0.als_enabled=1 +.Ed +.Pp +Enable Bluetooth: +.Bd -literal -offset indent +sysctl dev.acpi_hp.0.bt_enabled=1 +.Ed +.Pp +Get BIOS settings: +.Bd -literal -offset indent +cat /dev/hpcmi + +Serial Port Disable +Infrared Port Enable +Parallel Port Disable +Flash Media Reader Disable +USB Ports including Express Card slot Enable +1394 Port Enable +Cardbus Slot Disable +Express Card Slot Disable +(...) +.Ed +.Pp +Set maximum detail level for /dev/hpcmi output: +.Bd -literal -offset indent +sysctl dev.acpi_hp.0.cmi_detail=7 +.Ed +.Pp + + + +.Sh SEE ALSO +.Xr acpi 4 , +.Xr acpi_wmi 4 , +.Xr sysctl.conf 5 , +.Xr devd 8 , +.Xr devfs 8 , +.Xr sysctl 8 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Fx CURRENT . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Michael Gmelin Aq freebsd@grem.de +.Pp +It has been inspired by hp-wmi driver, which implements a subset of these +features (hotkeys) on Linux. +.Pp +.Bl -tag -width indent +.It HP CMI whitepaper: +http://h20331.www2.hp.com/Hpsub/downloads/cmi_whitepaper.pdf +.It wmi-hp for Linux: +http://www.kernel.org +.It WMI and ACPI: +http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx +.El +.Pp +This manual page was written by +.An Michael Gmelin Aq freebsd@grem.de +.Sh BUGS +This driver is experimental and has only been tested on CURRENT i386 on an +HP Compaq 8510p which featured all supported wireless devices (WWAN/BT/WLAN). +Expect undefined results when operating on different hardware. +.Pp +Loading the driver is slow. Reading from /dev/hpcmi is even slower. +.Pp +Additional features like HP specific sensor readings or writing BIOS +settings are not supported. --- sys/dev/acpi_support/acpi_hp.c~ 2009-06-21 18:50:08.924078040 +0200 +++ sys/dev/acpi_support/acpi_hp.c 2009-06-21 18:50:54.166723000 +0200 @@ -0,0 +1,1182 @@ +/*- + * Copyright (c) 2009 Michael Gmelin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * Driver for extra ACPI-controlled features found on HP laptops + * that use a WMI enabled BIOS (e.g. HP Compaq 8510p and 6510p). + * Allows to control and read status of integrated hardware and read + * BIOS settings through CMI. + * Inspired by the hp-wmi driver, which implements a subset of these + * features (hotkeys) on Linux. + * + * HP CMI whitepaper: + * http://h20331.www2.hp.com/Hpsub/downloads/cmi_whitepaper.pdf + * wmi-hp for Linux: + * http://www.kernel.org + * WMI and ACPI: + * http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx + */ + +#include "opt_acpi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "acpi_wmi_if.h" + +#define _COMPONENT ACPI_OEM +ACPI_MODULE_NAME("HP") + +#define ACPI_HP_WMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" +#define ACPI_HP_WMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" +#define ACPI_HP_WMI_CMI_GUID "2D114B49-2DFB-4130-B8FE-4A3C09E75133" + +#define ACPI_HP_WMI_DISPLAY_COMMAND 0x1 +#define ACPI_HP_WMI_HDDTEMP_COMMAND 0x2 +#define ACPI_HP_WMI_ALS_COMMAND 0x3 +#define ACPI_HP_WMI_DOCK_COMMAND 0x4 +#define ACPI_HP_WMI_WIRELESS_COMMAND 0x5 + +#define ACPI_HP_METHOD_WLAN_ENABLED 1 +#define ACPI_HP_METHOD_WLAN_RADIO 2 +#define ACPI_HP_METHOD_WLAN_ON_AIR 3 +#define ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON 4 +#define ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF 5 +#define ACPI_HP_METHOD_BLUETOOTH_ENABLED 6 +#define ACPI_HP_METHOD_BLUETOOTH_RADIO 7 +#define ACPI_HP_METHOD_BLUETOOTH_ON_AIR 8 +#define ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON 9 +#define ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF 10 +#define ACPI_HP_METHOD_WWAN_ENABLED 11 +#define ACPI_HP_METHOD_WWAN_RADIO 12 +#define ACPI_HP_METHOD_WWAN_ON_AIR 13 +#define ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON 14 +#define ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF 15 +#define ACPI_HP_METHOD_ALS 16 +#define ACPI_HP_METHOD_DISPLAY 17 +#define ACPI_HP_METHOD_HDDTEMP 18 +#define ACPI_HP_METHOD_DOCK 19 +#define ACPI_HP_METHOD_CMI_DETAIL 20 + +#define HP_MASK_WWAN_ON_AIR 0x1000000 +#define HP_MASK_BLUETOOTH_ON_AIR 0x10000 +#define HP_MASK_WLAN_ON_AIR 0x100 +#define HP_MASK_WWAN_RADIO 0x8000000 +#define HP_MASK_BLUETOOTH_RADIO 0x80000 +#define HP_MASK_WLAN_RADIO 0x800 +#define HP_MASK_WWAN_ENABLED 0x2000000 +#define HP_MASK_BLUETOOTH_ENABLED 0x20000 +#define HP_MASK_WLAN_ENABLED 0x200 + +#define ACPI_HP_CMI_DETAIL_PATHS 0x01 +#define ACPI_HP_CMI_DETAIL_ENUMS 0x02 +#define ACPI_HP_CMI_DETAIL_FLAGS 0x04 + +struct acpi_hp_inst_seq_pair { + UINT32 sequence; /* sequence number as suggested by cmi bios */ + UINT8 instance; /* object instance on guid */ +}; + +struct acpi_hp_softc { + device_t dev; + ACPI_HANDLE handle; + device_t wmi_dev; + int has_notify; /* notification GUID found */ + int has_cmi; /* CMI GUID found */ + int cmi_detail; /* CMI detail level + (set by sysctl) */ + int wlan_enable_if_radio_on; /* set by sysctl */ + int wlan_disable_if_radio_off; /* set by sysctl */ + int bluetooth_enable_if_radio_on; /* set by sysctl */ + int bluetooth_disable_if_radio_off; /* set by sysctl */ + int wwan_enable_if_radio_on; /* set by sysctl */ + int wwan_disable_if_radio_off; /* set by sysctl */ + int was_wlan_on_air; /* last known WLAN + on air status */ + int was_bluetooth_on_air; /* last known BT + on air status */ + int was_wwan_on_air; /* last known WWAN + on air status */ + struct sysctl_ctx_list *sysctl_ctx; + struct sysctl_oid *sysctl_tree; + struct cdev *hpcmi_dev_t; /* hpcmi device handle */ + struct sbuf hpcmi_sbuf; /* /dev/hpcmi output sbuf */ + pid_t hpcmi_open_pid; /* pid operating on + /dev/hpcmi */ + int hpcmi_bufptr; /* current pointer position + in /dev/hpcmi output buffer + */ + int cmi_order_size; /* size of cmi_order list */ + struct acpi_hp_inst_seq_pair cmi_order[128]; /* list of CMI + instances ordered by BIOS suggested sequence */ +}; + +static struct { + char *name; + int method; + char *description; + int access; +} acpi_hp_sysctls[] = { + { + .name = "wlan_enabled", + .method = ACPI_HP_METHOD_WLAN_ENABLED, + .description = "Enable/Disable WLAN (WiFi)", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wlan_radio", + .method = ACPI_HP_METHOD_WLAN_RADIO, + .description = "WLAN radio status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "wlan_on_air", + .method = ACPI_HP_METHOD_WLAN_ON_AIR, + .description = "WLAN radio ready to use (enabled and radio)", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "wlan_enable_if_radio_on", + .method = ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON, + .description = "Enable WLAN if radio is turned on", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wlan_disable_if_radio_off", + .method = ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF, + .description = "Disable WLAN if radio is turned off", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "bt_enabled", + .method = ACPI_HP_METHOD_BLUETOOTH_ENABLED, + .description = "Enable/Disable Bluetooth", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "bt_radio", + .method = ACPI_HP_METHOD_BLUETOOTH_RADIO, + .description = "Bluetooth radio status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "bt_on_air", + .method = ACPI_HP_METHOD_BLUETOOTH_ON_AIR, + .description = "Bluetooth radio ready to use" + " (enabled and radio)", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "bt_enable_if_radio_on", + .method = ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON, + .description = "Enable bluetooth if radio is turned on", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "bt_disable_if_radio_off", + .method = ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF, + .description = "Disable bluetooth if radio is turned off", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wwan_enabled", + .method = ACPI_HP_METHOD_WWAN_ENABLED, + .description = "Enable/Disable WWAN (UMTS)", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wwan_radio", + .method = ACPI_HP_METHOD_WWAN_RADIO, + .description = "WWAN radio status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "wwan_on_air", + .method = ACPI_HP_METHOD_WWAN_ON_AIR, + .description = "WWAN radio ready to use (enabled and radio)", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "wwan_enable_if_radio_on", + .method = ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON, + .description = "Enable WWAN if radio is turned on", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "wwan_disable_if_radio_off", + .method = ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF, + .description = "Disable WWAN if radio is turned off", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "als_enabled", + .method = ACPI_HP_METHOD_ALS, + .description = "Enable/Disable ALS (Ambient light sensor)", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + { + .name = "display", + .method = ACPI_HP_METHOD_DISPLAY, + .description = "Display status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "hdd_temperature", + .method = ACPI_HP_METHOD_HDDTEMP, + .description = "HDD temperature", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "is_docked", + .method = ACPI_HP_METHOD_DOCK, + .description = "Docking station status", + .access = CTLTYPE_INT | CTLFLAG_RD + }, + { + .name = "cmi_detail", + .method = ACPI_HP_METHOD_CMI_DETAIL, + .description = "Details shown in CMI output " + "(cat /dev/hpcmi)", + .access = CTLTYPE_INT | CTLFLAG_RW + }, + + { NULL, 0, NULL, 0 } +}; + +ACPI_SERIAL_DECL(hp, "HP ACPI-WMI Mapping"); + +static int acpi_hp_probe(device_t dev); +static int acpi_hp_attach(device_t dev); +static int acpi_hp_detach(device_t dev); + +static void acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc* sc); +static int acpi_hp_sysctl(SYSCTL_HANDLER_ARGS); +static int acpi_hp_sysctl_set(struct acpi_hp_softc *sc, int method, + int arg, int oldarg); +static int acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method); +static int acpi_hp_exec_wmi_command(device_t wmi_dev, int command, + int is_write, int val); +static void acpi_hp_notify(ACPI_HANDLE h, UINT32 notify, void *context); +static int acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, + UINT8 instance, char* outbuf, size_t outsize, + UINT32* sequence, int detail); +static void acpi_hp_hex_decode(char* buffer); + +static d_open_t acpi_hp_hpcmi_open; +static d_close_t acpi_hp_hpcmi_close; +static d_read_t acpi_hp_hpcmi_read; + +/* handler /dev/hpcmi device */ +static struct cdevsw hpcmi_cdevsw = { + .d_version = D_VERSION, + .d_open = acpi_hp_hpcmi_open, + .d_close = acpi_hp_hpcmi_close, + .d_read = acpi_hp_hpcmi_read, + .d_name = "hpcmi", +}; + +static device_method_t acpi_hp_methods[] = { + DEVMETHOD(device_probe, acpi_hp_probe), + DEVMETHOD(device_attach, acpi_hp_attach), + DEVMETHOD(device_detach, acpi_hp_detach), + {0, 0} +}; + +static driver_t acpi_hp_driver = { + "acpi_hp", + acpi_hp_methods, + sizeof(struct acpi_hp_softc), +}; + +static devclass_t acpi_hp_devclass; + +DRIVER_MODULE(acpi_hp, acpi, acpi_hp_driver, acpi_hp_devclass, + 0, 0); +MODULE_DEPEND(acpi_hp, acpi_wmi, 1, 1, 1); +MODULE_DEPEND(acpi_hp, acpi, 1, 1, 1); + +static void +acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc *sc) +{ + int wireless; + int new_wlan_status; + int new_bluetooth_status; + int new_wwan_status; + + wireless = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + new_wlan_status = -1; + new_bluetooth_status = -1; + new_wwan_status = -1; + + device_printf(sc->wmi_dev, "Wireless status is %x\n", wireless); + if (sc->wlan_disable_if_radio_off && !(wireless & HP_MASK_WLAN_RADIO) + && (wireless & HP_MASK_WLAN_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x100); + new_wlan_status = 0; + } + else if (sc->wlan_enable_if_radio_on && (wireless & HP_MASK_WLAN_RADIO) + && !(wireless & HP_MASK_WLAN_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x101); + new_wlan_status = 1; + } + if (sc->bluetooth_disable_if_radio_off && + !(wireless & HP_MASK_BLUETOOTH_RADIO) && + (wireless & HP_MASK_BLUETOOTH_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x200); + new_bluetooth_status = 0; + } + else if (sc->bluetooth_enable_if_radio_on && + (wireless & HP_MASK_BLUETOOTH_RADIO) && + !(wireless & HP_MASK_BLUETOOTH_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x202); + new_bluetooth_status = 1; + } + if (sc->wwan_disable_if_radio_off && + !(wireless & HP_MASK_WWAN_RADIO) && + (wireless & HP_MASK_WWAN_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x400); + new_wwan_status = 0; + } + else if (sc->wwan_enable_if_radio_on && + (wireless & HP_MASK_WWAN_RADIO) && + !(wireless & HP_MASK_WWAN_ENABLED)) { + acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x404); + new_wwan_status = 1; + } + + if (new_wlan_status == -1) { + new_wlan_status = (wireless & HP_MASK_WLAN_ON_AIR); + if ((new_wlan_status?1:0) != sc->was_wlan_on_air) { + sc->was_wlan_on_air = sc->was_wlan_on_air?0:1; + device_printf(sc->wmi_dev, + "WLAN on air changed to %i " + "(new_wlan_status is %i)\n", + sc->was_wlan_on_air, new_wlan_status); + acpi_UserNotify("HP", sc->handle, + 0xc0+sc->was_wlan_on_air); + } + } + if (new_bluetooth_status == -1) { + new_bluetooth_status = (wireless & HP_MASK_BLUETOOTH_ON_AIR); + if ((new_bluetooth_status?1:0) != sc->was_bluetooth_on_air) { + sc->was_bluetooth_on_air = sc->was_bluetooth_on_air? + 0:1; + device_printf(sc->wmi_dev, "BLUETOOTH on air changed" + " to %i (new_bluetooth_status is %i)\n", + sc->was_bluetooth_on_air, new_bluetooth_status); + acpi_UserNotify("HP", sc->handle, + 0xd0+sc->was_bluetooth_on_air); + } + } + if (new_wwan_status == -1) { + new_wwan_status = (wireless & HP_MASK_WWAN_ON_AIR); + if ((new_wwan_status?1:0) != sc->was_wwan_on_air) { + sc->was_wwan_on_air = sc->was_wwan_on_air?0:1; + device_printf(sc->wmi_dev, "WWAN on air changed to %i" + " (new_wwan_status is %i)\n", + sc->was_wwan_on_air, new_wwan_status); + acpi_UserNotify("HP", sc->handle, + 0xe0+sc->was_wwan_on_air); + } + } +} + +static int +acpi_hp_probe(device_t dev) +{ + if (acpi_disabled("hp") || device_get_unit(dev) != 0) + return (ENXIO); + device_set_desc(dev, "HP ACPI-WMI Mapping"); + + return (0); +} + +static int +acpi_hp_attach(device_t dev) +{ + struct acpi_hp_softc *sc; + struct acpi_softc *acpi_sc; + devclass_t wmi_devclass; + int arg; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); + + sc = device_get_softc(dev); + sc->dev = dev; + sc->handle = acpi_get_handle(dev); + sc->has_notify = 0; + sc->has_cmi = 0; + sc->bluetooth_enable_if_radio_on = 0; + sc->bluetooth_disable_if_radio_off = 0; + sc->wlan_enable_if_radio_on = 0; + sc->wlan_disable_if_radio_off = 0; + sc->wlan_enable_if_radio_on = 0; + sc->wlan_disable_if_radio_off = 0; + sc->was_wlan_on_air = 0; + sc->was_bluetooth_on_air = 0; + sc->was_wwan_on_air = 0; + sc->cmi_detail = 0; + sc->cmi_order_size = -1; + memset(sc->cmi_order, 0, sizeof(sc->cmi_order)); + acpi_sc = acpi_device_get_parent_softc(dev); + + if (!(wmi_devclass = devclass_find ("acpi_wmi"))) { + device_printf(dev, "Couldn't find acpi_wmi devclass\n"); + return (EINVAL); + } + if (!(sc->wmi_dev = devclass_get_device(wmi_devclass, 0))) { + device_printf(dev, "Couldn't find acpi_wmi device\n"); + return (EINVAL); + } + if (!ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, + ACPI_HP_WMI_BIOS_GUID)) { + device_printf(dev, + "WMI device does not provide the HP BIOS GUID\n"); + return (EINVAL); + } + if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, + ACPI_HP_WMI_EVENT_GUID)) { + device_printf(dev, + "HP event GUID detected, installing event handler\n"); + if (ACPI_WMI_INSTALL_EVENT_HANDLER(sc->wmi_dev, + ACPI_HP_WMI_EVENT_GUID, acpi_hp_notify, dev)) { + device_printf(dev, + "Could not install notification handler!\n"); + } + else { + sc->has_notify = 1; + } + } + if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID)) { + device_printf(dev, "HP CMI GUID detected\n"); + sc->has_cmi = 1; + } + + if (sc->has_cmi) { + sc->hpcmi_dev_t = make_dev(&hpcmi_cdevsw, 0, UID_ROOT, + GID_WHEEL, 0644, "hpcmi"); + sc->hpcmi_dev_t->si_drv1 = sc; + sc->hpcmi_open_pid = 0; + sc->hpcmi_bufptr = -1; + } + + ACPI_SERIAL_BEGIN(hp); + + sc->sysctl_ctx = device_get_sysctl_ctx(dev); + sc->sysctl_tree = device_get_sysctl_tree(dev); + for (int i = 0; acpi_hp_sysctls[i].name != NULL; ++i) { + arg = 0; + if ((!sc->has_notify && + (acpi_hp_sysctls[i].method == + ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON || + acpi_hp_sysctls[i].method == + ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF || + acpi_hp_sysctls[i].method == + ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON || + acpi_hp_sysctls[i].method == + ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF || + acpi_hp_sysctls[i].method == + ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON || + acpi_hp_sysctls[i].method == + ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF)) || + (arg = acpi_hp_sysctl_get(sc, + acpi_hp_sysctls[i].method)) < 0) { + continue; + } + if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_ON_AIR) { + sc->was_wlan_on_air = arg; + } + else if (acpi_hp_sysctls[i].method == + ACPI_HP_METHOD_BLUETOOTH_ON_AIR) { + sc->was_bluetooth_on_air = arg; + } + else if (acpi_hp_sysctls[i].method == + ACPI_HP_METHOD_WWAN_ON_AIR) { + sc->was_wwan_on_air = arg; + } + + SYSCTL_ADD_PROC(sc->sysctl_ctx, + SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, + acpi_hp_sysctls[i].name, acpi_hp_sysctls[i].access, + sc, i, acpi_hp_sysctl, "I", + acpi_hp_sysctls[i].description); + } + ACPI_SERIAL_END(hp); + + return (0); +} + +static int +acpi_hp_detach(device_t dev) +{ + int ret; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); + struct acpi_hp_softc *sc = device_get_softc(dev); + if (sc->has_cmi && sc->hpcmi_open_pid != 0) { + ret = EBUSY; + } + else { + if (sc->has_notify) { + ACPI_WMI_REMOVE_EVENT_HANDLER(dev, + ACPI_HP_WMI_EVENT_GUID); + } + if (sc->hpcmi_bufptr != -1) { + sbuf_delete(&sc->hpcmi_sbuf); + sc->hpcmi_bufptr = -1; + } + sc->hpcmi_open_pid = 0; + destroy_dev(sc->hpcmi_dev_t); + ret = 0; + } + + return (ret); +} + +static int +acpi_hp_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct acpi_hp_softc *sc; + int arg; + int oldarg; + int error = 0; + int function; + int method; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = (struct acpi_hp_softc *)oidp->oid_arg1; + function = oidp->oid_arg2; + method = acpi_hp_sysctls[function].method; + + ACPI_SERIAL_BEGIN(hp); + arg = acpi_hp_sysctl_get(sc, method); + oldarg = arg; + error = sysctl_handle_int(oidp, &arg, 0, req); + if (!error && req->newptr != NULL) { + error = acpi_hp_sysctl_set(sc, method, arg, oldarg); + } + ACPI_SERIAL_END(hp); + + return (error); +} + +static int +acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method) +{ + int val = 0; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + ACPI_SERIAL_ASSERT(hp); + + switch (method) { + case ACPI_HP_METHOD_WLAN_ENABLED: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WLAN_ENABLED) != 0); + break; + case ACPI_HP_METHOD_WLAN_RADIO: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WLAN_RADIO) != 0); + break; + case ACPI_HP_METHOD_WLAN_ON_AIR: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WLAN_ON_AIR) != 0); + break; + case ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON: + val = sc->wlan_enable_if_radio_on; + break; + case ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF: + val = sc->wlan_disable_if_radio_off; + break; + case ACPI_HP_METHOD_BLUETOOTH_ENABLED: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_BLUETOOTH_ENABLED) != 0); + break; + case ACPI_HP_METHOD_BLUETOOTH_RADIO: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_BLUETOOTH_RADIO) != 0); + break; + case ACPI_HP_METHOD_BLUETOOTH_ON_AIR: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_BLUETOOTH_ON_AIR) != 0); + break; + case ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON: + val = sc->bluetooth_enable_if_radio_on; + break; + case ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF: + val = sc->bluetooth_disable_if_radio_off; + break; + case ACPI_HP_METHOD_WWAN_ENABLED: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WWAN_ENABLED) != 0); + break; + case ACPI_HP_METHOD_WWAN_RADIO: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WWAN_RADIO) != 0); + break; + case ACPI_HP_METHOD_WWAN_ON_AIR: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); + val = ((val & HP_MASK_WWAN_ON_AIR) != 0); + break; + case ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON: + val = sc->wwan_enable_if_radio_on; + break; + case ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF: + val = sc->wwan_disable_if_radio_off; + break; + case ACPI_HP_METHOD_ALS: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_ALS_COMMAND, 0, 0); + break; + case ACPI_HP_METHOD_DISPLAY: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_DISPLAY_COMMAND, 0, 0); + break; + case ACPI_HP_METHOD_HDDTEMP: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_HDDTEMP_COMMAND, 0, 0); + break; + case ACPI_HP_METHOD_DOCK: + val = acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_DOCK_COMMAND, 0, 0); + break; + case ACPI_HP_METHOD_CMI_DETAIL: + val = sc->cmi_detail; + break; + } + + return (val); +} + +static int +acpi_hp_sysctl_set(struct acpi_hp_softc *sc, int method, int arg, int oldarg) +{ + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + ACPI_SERIAL_ASSERT(hp); + + if (method != ACPI_HP_METHOD_CMI_DETAIL) + arg = arg?1:0; + + if (arg != oldarg) { + switch (method) { + case ACPI_HP_METHOD_WLAN_ENABLED: + return (acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, + arg?0x101:0x100)); + case ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON: + sc->wlan_enable_if_radio_on = arg; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF: + sc->wlan_disable_if_radio_off = arg; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_BLUETOOTH_ENABLED: + return (acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, + arg?0x202:0x200)); + case ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON: + sc->bluetooth_enable_if_radio_on = arg; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF: + sc->bluetooth_disable_if_radio_off = arg?1:0; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_WWAN_ENABLED: + return (acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_WIRELESS_COMMAND, 1, + arg?0x404:0x400)); + case ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON: + sc->wwan_enable_if_radio_on = arg?1:0; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF: + sc->wwan_disable_if_radio_off = arg?1:0; + acpi_hp_evaluate_auto_on_off(sc); + break; + case ACPI_HP_METHOD_ALS: + return (acpi_hp_exec_wmi_command(sc->wmi_dev, + ACPI_HP_WMI_ALS_COMMAND, 1, + arg?1:0)); + case ACPI_HP_METHOD_CMI_DETAIL: + sc->cmi_detail = arg; + break; + } + } + + return (0); +} + +static __inline void +acpi_hp_free_buffer(ACPI_BUFFER* buf) { + if (buf && buf->Pointer) { + AcpiOsFree(buf->Pointer); + } +} + +static void +acpi_hp_notify(ACPI_HANDLE h, UINT32 notify, void *context) +{ + device_t dev = context; + ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); + + struct acpi_hp_softc *sc = device_get_softc(dev); + ACPI_BUFFER response = { ACPI_ALLOCATE_BUFFER, NULL }; + ACPI_OBJECT *obj; + ACPI_WMI_GET_EVENT_DATA(sc->wmi_dev, notify, &response); + obj = (ACPI_OBJECT*) response.Pointer; + if (obj && obj->Type == ACPI_TYPE_BUFFER && obj->Buffer.Length == 8) { + if (*((UINT8 *) obj->Buffer.Pointer) == 0x5) { + acpi_hp_evaluate_auto_on_off(sc); + } + } + acpi_hp_free_buffer(&response); +} + +static int +acpi_hp_exec_wmi_command(device_t wmi_dev, int command, int is_write, int val) +{ + UINT32 params[5] = { 0x55434553, + is_write?2:1, + command, + is_write?4:0, + val}; + UINT32* result; + ACPI_OBJECT *obj; + ACPI_BUFFER in = { sizeof(params), ¶ms }; + ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; + int retval; + + if (ACPI_FAILURE(ACPI_WMI_EVALUATE_CALL(wmi_dev, ACPI_HP_WMI_BIOS_GUID, + 0, 0x3, &in, &out))) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } + obj = out.Pointer; + if (!obj || obj->Type != ACPI_TYPE_BUFFER) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } + result = (UINT32*) obj->Buffer.Pointer; + retval = result[2]; + if (result[1] > 0) { + retval = result[1]; + } + acpi_hp_free_buffer(&out); + + return (retval); +} + +static __inline char* +acpi_hp_get_string_from_object(ACPI_OBJECT* obj, char* dst, size_t size) { + int length; + dst[0] = 0; + if (obj->Type == ACPI_TYPE_STRING) { + length = obj->String.Length+1; + if (length > size) { + length = size - 1; + } + strlcpy(dst, obj->String.Pointer, length); + acpi_hp_hex_decode(dst); + } + + return (dst); +} + + +/* + * Read BIOS Setting block in instance "instance". + * The block returned is ACPI_TYPE_PACKAGE which should contain the following + * elements: + * Index Meaning + * 0 Setting Name [string] + * 1 Value (comma separated, asterisk marks the current value) [string] + * 2 Path within the bios hierarchy [string] + * 3 IsReadOnly [int] + * 4 DisplayInUI [int] + * 5 RequiresPhysicalPresence [int] + * 6 Sequence for ordering within the bios settings (absolute) [int] + * 7 Length of prerequisites array [int] + * 8 Prerequisite1 [string] + * 9 Prerequisite2 [string] + * 10 Prerequisite3 [string] + * 11 Current value (in case of enum) [string] / Array length [int] + * 12 Enum length [int] / Array values + * 13ff Enum value at index x [string] + */ +static int +acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, UINT8 instance, + char* outbuf, size_t outsize, UINT32* sequence, int detail) +{ + ACPI_OBJECT *obj; + ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; + int i; + int outlen; + int size = 255; + int has_enums = 0; + char string_buffer[size]; + int enumbase; + + outlen = 0; + outbuf[0] = 0; + if (ACPI_FAILURE(ACPI_WMI_GET_BLOCK(wmi_dev, guid, instance, &out))) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } + obj = out.Pointer; + if (!obj && obj->Type != ACPI_TYPE_PACKAGE) { + acpi_hp_free_buffer(&out); + return (-EINVAL); + } + + /* check if this matches our expectations based on limited knowledge */ + if (obj->Package.Count >= 13 && + obj->Package.Elements[0].Type == ACPI_TYPE_STRING && + obj->Package.Elements[1].Type == ACPI_TYPE_STRING && + obj->Package.Elements[2].Type == ACPI_TYPE_STRING && + obj->Package.Elements[3].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[4].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[5].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[6].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[7].Type == ACPI_TYPE_INTEGER && + obj->Package.Elements[8].Type == ACPI_TYPE_STRING && + obj->Package.Elements[9].Type == ACPI_TYPE_STRING && + obj->Package.Elements[10].Type == ACPI_TYPE_STRING && + ((obj->Package.Elements[11].Type == ACPI_TYPE_STRING && + obj->Package.Elements[12].Type == ACPI_TYPE_INTEGER && + obj->Package.Count >= + 13+obj->Package.Elements[12].Integer.Value) || + (obj->Package.Elements[11].Type == ACPI_TYPE_INTEGER && + obj->Package.Count >= + 12+obj->Package.Elements[11].Integer.Value)) + ) { + enumbase = obj->Package.Elements[11].Type == ACPI_TYPE_STRING? + 12:11; + if (detail & ACPI_HP_CMI_DETAIL_PATHS) { + strlcat(outbuf, acpi_hp_get_string_from_object( + &obj->Package.Elements[2], string_buffer, size), + outsize); + outlen += 48; + while (strlen(outbuf) < outlen) + strlcat(outbuf, " ", outsize); + } + strlcat(outbuf, acpi_hp_get_string_from_object( + &obj->Package.Elements[0], string_buffer, size), + outsize); + outlen += 43; + while (strlen(outbuf) < outlen) + strlcat(outbuf, " ", outsize); + if (enumbase == 12) + strlcat(outbuf, acpi_hp_get_string_from_object( + &obj->Package.Elements[11], + string_buffer, size), + outsize); + outlen += 21; + while (strlen(outbuf) < outlen) + strlcat(outbuf, " ", outsize); + for (i = 0; i < strlen(outbuf); ++i) + if (outbuf[i] == '\\') + outbuf[i] = '/'; + if (detail & ACPI_HP_CMI_DETAIL_ENUMS) { + for (i = enumbase+1; i < enumbase + 1 + + obj->Package.Elements[enumbase].Integer.Value; + ++i) { + acpi_hp_get_string_from_object( + &obj->Package.Elements[i], string_buffer, + size); + if (strlen(string_buffer) > 1 || + (strlen(string_buffer) == 1 && + string_buffer[0] != ' ')) { + if (has_enums) + strlcat(outbuf, "/", outsize); + else + strlcat(outbuf, " (", outsize); + strlcat(outbuf, string_buffer, outsize); + has_enums = 1; + } + } + } + if (has_enums) + strlcat(outbuf, ")", outsize); + if (detail & ACPI_HP_CMI_DETAIL_FLAGS) { + strlcat(outbuf, obj->Package.Elements[3].Integer.Value? + " [ReadOnly]":"", outsize); + strlcat(outbuf, obj->Package.Elements[4].Integer.Value? + "":" [NOUI]", outsize); + strlcat(outbuf, obj->Package.Elements[5].Integer.Value? + " [RPP]":"", outsize); + } + *sequence = (UINT32) obj->Package.Elements[6].Integer.Value; + } + acpi_hp_free_buffer(&out); + + return (0); +} + + + +/* + * Convert given two digit hex string (hexin) to an UINT8 referenced + * by byteout. + * Return != 0 if the was a problem (invalid input) + */ +static __inline int acpi_hp_hex_to_int(const UINT8 *hexin, UINT8 *byteout) +{ + unsigned int hi; + unsigned int lo; + + hi = hexin[0]; + lo = hexin[1]; + if ('0' <= hi && hi <= '9') + hi -= '0'; + else if ('A' <= hi && hi <= 'F') + hi -= ('A' - 10); + else if ('a' <= hi && hi <= 'f') + hi -= ('a' - 10); + else + return (1); + if ('0' <= lo && lo <= '9') + lo -= '0'; + else if ('A' <= lo && lo <= 'F') + lo -= ('A' - 10); + else if ('a' <= lo && lo <= 'f') + lo -= ('a' - 10); + else + return (1); + *byteout = (hi << 4) + lo; + + return (0); +} + + +static void +acpi_hp_hex_decode(char* buffer) +{ + int i; + int length = strlen(buffer); + UINT8 *uin; + UINT8 uout; + + if (((int)length/2)*2 == length || length < 10) return; + + for (i = 0; i= '0' && buffer[i] <= '9') || + (buffer[i] >= 'A' && buffer[i] <= 'F'))) + return; + } + + for (i = 0; isi_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(hp); + if (sc->hpcmi_open_pid != 0) { + ret = EBUSY; + } + else { + if (sbuf_new(&sc->hpcmi_sbuf, NULL, 4096, SBUF_AUTOEXTEND) + == NULL) { + ret = ENXIO; + } else { + sc->hpcmi_open_pid = td->td_proc->p_pid; + sc->hpcmi_bufptr = 0; + ret = 0; + } + } + ACPI_SERIAL_END(hp); + + return (ret); +} + +/* + * close hpcmi device + */ +static int +acpi_hp_hpcmi_close(struct cdev* dev, int flags, int mode, struct thread *td) +{ + struct acpi_hp_softc *sc; + int ret; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(hp); + if (sc->hpcmi_open_pid == 0) { + ret = EBADF; + } + else { + if (sc->hpcmi_bufptr != -1) { + sbuf_delete(&sc->hpcmi_sbuf); + sc->hpcmi_bufptr = -1; + } + sc->hpcmi_open_pid = 0; + ret = 0; + } + ACPI_SERIAL_END(hp); + + return (ret); +} + +/* + * Read from hpcmi bios information + */ +static int +acpi_hp_hpcmi_read(struct cdev *dev, struct uio *buf, int flag) +{ + struct acpi_hp_softc *sc; + int pos, i, l, ret; + UINT8 instance; + UINT32 sequence; + int linesize = 1025; + char line[linesize]; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(hp); + if (sc->hpcmi_open_pid != buf->uio_td->td_proc->p_pid + || sc->hpcmi_bufptr == -1) { + ret = EBADF; + } + else { + if (!sbuf_done(&sc->hpcmi_sbuf)) { + if (sc->cmi_order_size < 0) { + sc->cmi_order_size = 0; + for (instance = 0; instance < 128; + ++instance) { + if (acpi_hp_get_cmi_block(sc->wmi_dev, + ACPI_HP_WMI_CMI_GUID, instance, + line, linesize, &sequence, + sc->cmi_detail)) { + instance = 128; + } + else { + pos = sc->cmi_order_size; + for (i=0; + icmi_order_size && i<127; + ++i) { + if (sc->cmi_order[i].sequence > sequence) { + pos = i; + break; + } + } + for (i=sc->cmi_order_size; + i>pos; + --i) { + sc->cmi_order[i].sequence = + sc->cmi_order[i-1].sequence; + sc->cmi_order[i].instance = + sc->cmi_order[i-1].instance; + } + sc->cmi_order[pos].sequence = + sequence; + sc->cmi_order[pos].instance = + instance; + sc->cmi_order_size++; + } + } + } + for (i=0; icmi_order_size; ++i) { + if (!acpi_hp_get_cmi_block(sc->wmi_dev, + ACPI_HP_WMI_CMI_GUID, + sc->cmi_order[i].instance, line, linesize, + &sequence, sc->cmi_detail)) { + sbuf_printf(&sc->hpcmi_sbuf, "%s\n", line); + } + } + sbuf_finish(&sc->hpcmi_sbuf); + } + if (sbuf_len(&sc->hpcmi_sbuf) <= 0) { + sbuf_delete(&sc->hpcmi_sbuf); + sc->hpcmi_bufptr = -1; + sc->hpcmi_open_pid = 0; + ret = ENOMEM; + } else { + l = min(buf->uio_resid, sbuf_len(&sc->hpcmi_sbuf) - + sc->hpcmi_bufptr); + ret = (l > 0)?uiomove(sbuf_data(&sc->hpcmi_sbuf) + + sc->hpcmi_bufptr, l, buf) : 0; + sc->hpcmi_bufptr += l; + } + } + ACPI_SERIAL_END(hp); + + return (ret); +} --- share/man/man4/man4.i386/acpi_wmi.4~ 2009-06-21 12:09:58.000000000 +0200 +++ share/man/man4/man4.i386/acpi_wmi.4 2009-06-21 12:10:57.178932778 +0200 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2009 Michael Gmelin +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 21, 2009 +.Dt ACPI_WMI 4 i386 +.Os +.Sh NAME +.Nm acpi_wmi +.Nd "ACPI to WMI mapping driver" +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following line in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device acpi_wmi" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +acpi_wmi_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides an interface for vendor specific WMI implementations +(e.g. HP and Acer laptops). It creates /dev/wmistat, which can be read to get +information about GUIDs found in the system. +.Sh FILES +.Bl -tag -width /dev/wmistat -compact +.It Pa /dev/wmistat +WMI status device. +.El +.Sh EXAMPLES +.Bd Literal +root# cat /dev/wmistat + +GUID INST EXPE METH STR EVENT OID +{5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA +{95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - +{2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - +{05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB +{1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA +{2D114B49-2DFB-4130-B8FE-4A3C09E75133} 57 NO NO NO NO BC +{988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 20 NO NO NO NO BD +{14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE +{322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF +{8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG +{8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH +{8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI +.Ed + +.Sh SEE ALSO +.Xr acpi 4 , +.Sh HISTORY +The +.Nm +device driver first appeared in +.Fx CURRENT . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Michael Gmelin Aq freebsd@grem.de +.Pp +Work has been inspired by the Linux acpi-wmi driver written by Carlos Corbacho +.Pp +See http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx for +the specification of ACPI-WMI. +.Pp +This manual page was written by +.An Michael Gmelin Aq freebsd@grem.de --- sys/dev/acpi_support/acpi_wmi.c~ 2009-06-21 18:42:25.739784505 +0200 +++ sys/dev/acpi_support/acpi_wmi.c 2009-06-21 18:50:54.166723000 +0200 @@ -0,0 +1,1005 @@ +/*- + * Copyright (c) 2009 Michael Gmelin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * Driver for acpi-wmi mapping, provides an interface for vendor specific + * implementations (e.g. HP and Acer laptops). + * Inspired by the ACPI-WMI mapping driver (c) 2008-2008 Carlos Corbacho which + * implements this functionality for Linux. + * + * WMI and ACPI: http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx + * acpi-wmi for Linux: http://www.kernel.org + */ + +#include "opt_acpi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "acpi_wmi_if.h" + +MALLOC_DEFINE(M_ACPIWMI, "acpiwmi", "ACPI-WMI mapping"); + +#define _COMPONENT ACPI_OEM +ACPI_MODULE_NAME("ACPI_WMI"); + +#define ACPI_WMI_REGFLAG_EXPENSIVE 0x1 /* GUID flag: Expensive operation */ +#define ACPI_WMI_REGFLAG_METHOD 0x2 /* GUID flag: Method call */ +#define ACPI_WMI_REGFLAG_STRING 0x4 /* GUID flag: String */ +#define ACPI_WMI_REGFLAG_EVENT 0x8 /* GUID flag: Event */ + +/* + * acpi_wmi driver private structure + */ +struct acpi_wmi_softc { + device_t wmi_dev; /* wmi device id */ + ACPI_HANDLE wmi_handle; /* handle of the PNP0C14 node */ + device_t ec_dev; /* acpi_ec0 */ + struct cdev *wmistat_dev_t; /* wmistat device handle */ + struct sbuf wmistat_sbuf; /* sbuf for /dev/wmistat output */ + pid_t wmistat_open_pid; /* pid operating on /dev/wmistat */ + int wmistat_bufptr; /* /dev/wmistat ptr to buffer position */ +}; + +/* + * Struct that holds information about + * about a single GUID entry in _WDG + */ +struct guid_info { + char guid[16]; /* 16 byte non human readable GUID */ + char oid[2]; /* object id or event notify id (first byte) */ + UINT8 max_instance; /* highest instance known for this GUID */ + UINT8 flags; /* ACPI_WMI_REGFLAG_%s */ +}; + +/* WExx event generation state (on/off) */ +enum event_generation_state { + EVENT_GENERATION_ON = 1, + EVENT_GENERATION_OFF = 0 +}; + + +/* + * Information about one entry in _WDG. + * List of those is used to lookup information by GUID. + */ +struct wmi_info { + TAILQ_ENTRY(wmi_info) wmi_list; + struct guid_info ginfo; /* information on guid */ + ACPI_NOTIFY_HANDLER event_handler;/* client provided event handler */ + void *event_handler_user_data; /* ev handler cookie */ +}; + +TAILQ_HEAD(wmi_info_list_head, wmi_info) + wmi_info_list = TAILQ_HEAD_INITIALIZER(wmi_info_list); + +ACPI_SERIAL_DECL(acpi_wmi, "ACPI-WMI Mapping"); + +/* public interface - declaration */ +/* standard device interface*/ +static int acpi_wmi_probe(device_t dev); +static int acpi_wmi_attach(device_t dev); +static int acpi_wmi_detach(device_t dev); +/* see acpi_wmi_if.m */ +static int acpi_wmi_provides_guid_string_method(device_t dev, + const char *guid_string); +static ACPI_STATUS acpi_wmi_evaluate_call_method(device_t dev, + const char *guid_string, UINT8 instance, + UINT32 method_id, const ACPI_BUFFER *in, + ACPI_BUFFER *out); +static ACPI_STATUS acpi_wmi_install_event_handler_method(device_t dev, + const char *guid_string, ACPI_NOTIFY_HANDLER handler, + void *data); +static ACPI_STATUS acpi_wmi_remove_event_handler_method(device_t dev, + const char *guid_string); +static ACPI_STATUS acpi_wmi_get_event_data_method(device_t dev, + UINT32 event_id, ACPI_BUFFER *out); +static ACPI_STATUS acpi_wmi_get_block_method(device_t dev, + const char *guid_string, + UINT8 instance, ACPI_BUFFER *out); +static ACPI_STATUS acpi_wmi_set_block_method(device_t dev, + const char *guid_string, + UINT8 instance, const ACPI_BUFFER *in); +/* private interface - declaration */ +/* callbacks */ +static void acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, + void *context); +static ACPI_STATUS acpi_wmi_ec_handler(UINT32 function, + ACPI_PHYSICAL_ADDRESS address, UINT32 width, + ACPI_INTEGER *value, void *context, + void *region_context); +/* helpers */ +static ACPI_STATUS acpi_wmi_read_wdg_blocks(ACPI_HANDLE h); +static ACPI_STATUS acpi_wmi_toggle_we_event_generation(device_t dev, + struct wmi_info *winfo, + enum event_generation_state state); +static int acpi_wmi_guid_string_to_guid(const UINT8 *guid_string, + UINT8 *guid); +static struct wmi_info* acpi_wmi_lookup_wmi_info_by_guid_string( + const char *guid_string); + +static d_open_t acpi_wmi_wmistat_open; +static d_close_t acpi_wmi_wmistat_close; +static d_read_t acpi_wmi_wmistat_read; + +/* handler /dev/wmistat device */ +static struct cdevsw wmistat_cdevsw = { + .d_version = D_VERSION, + .d_open = acpi_wmi_wmistat_open, + .d_close = acpi_wmi_wmistat_close, + .d_read = acpi_wmi_wmistat_read, + .d_name = "wmistat", +}; + + +static device_method_t acpi_wmi_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, acpi_wmi_probe), + DEVMETHOD(device_attach, acpi_wmi_attach), + DEVMETHOD(device_detach, acpi_wmi_detach), + + /* acpi_wmi interface */ + DEVMETHOD(acpi_wmi_provides_guid_string, + acpi_wmi_provides_guid_string_method), + DEVMETHOD(acpi_wmi_evaluate_call, acpi_wmi_evaluate_call_method), + DEVMETHOD(acpi_wmi_install_event_handler, + acpi_wmi_install_event_handler_method), + DEVMETHOD(acpi_wmi_remove_event_handler, + acpi_wmi_remove_event_handler_method), + DEVMETHOD(acpi_wmi_get_event_data, acpi_wmi_get_event_data_method), + DEVMETHOD(acpi_wmi_get_block, acpi_wmi_get_block_method), + DEVMETHOD(acpi_wmi_set_block, acpi_wmi_set_block_method), + + {0, 0} +}; + +static driver_t acpi_wmi_driver = { + "acpi_wmi", + acpi_wmi_methods, + sizeof(struct acpi_wmi_softc), +}; + +static devclass_t acpi_wmi_devclass; +DRIVER_MODULE(acpi_wmi, acpi, acpi_wmi_driver, acpi_wmi_devclass, 0, 0); +MODULE_VERSION(acpi_wmi, 1); +MODULE_DEPEND(acpi_wmi, acpi, 1, 1, 1); +static char *wmi_ids[] = {"PNP0C14", "PNP0c14", NULL}; + +/* + * Probe for the PNP0C14 ACPI node + */ +static int +acpi_wmi_probe(device_t dev) +{ + if (acpi_disabled("wmi") || + ACPI_ID_PROBE(device_get_parent(dev), dev, wmi_ids) == NULL) + return (ENXIO); + device_set_desc(dev, "ACPI-WMI mapping"); + + return (0); +} + +/* + * Attach the device by: + * - Looking for the first ACPI EC device + * - Install the notify handler + * - Install the EC address space handler + * - Look for the _WDG node and read GUID information blocks + */ +static int +acpi_wmi_attach(device_t dev) +{ + struct acpi_wmi_softc *sc; + int ret; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + sc = device_get_softc(dev); + ret = ENXIO; + + ACPI_SERIAL_BEGIN(acpi_wmi); + sc->wmi_dev = dev; + sc->wmi_handle = acpi_get_handle(dev); + TAILQ_INIT(&wmi_info_list); + /* XXX Only works with one EC, but nearly all systems only have one. */ + if ((sc->ec_dev = devclass_get_device(devclass_find("acpi_ec"), 0)) + == NULL) + device_printf(dev, "cannot find EC device\n"); + else if (ACPI_FAILURE((status = AcpiInstallNotifyHandler(sc->wmi_handle, + ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler, sc)))) + device_printf(sc->wmi_dev, "couldn't install notify handler - %s\n", + AcpiFormatException(status)); + else if (ACPI_FAILURE((status = AcpiInstallAddressSpaceHandler( + sc->wmi_handle, ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler, + NULL, sc)))) { + device_printf(sc->wmi_dev, "couldn't install EC handler - %s\n", + AcpiFormatException(status)); + AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, + acpi_wmi_notify_handler); + } else if (ACPI_FAILURE((status = acpi_wmi_read_wdg_blocks( + sc->wmi_handle)))) { + device_printf(sc->wmi_dev, "couldn't parse _WDG - %s\n", + AcpiFormatException(status)); + AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, + acpi_wmi_notify_handler); + AcpiRemoveAddressSpaceHandler(sc->wmi_handle, ACPI_ADR_SPACE_EC, + acpi_wmi_ec_handler); + } else { + sc->wmistat_dev_t = make_dev(&wmistat_cdevsw, 0, UID_ROOT, + GID_WHEEL, 0644, "wmistat"); + sc->wmistat_dev_t->si_drv1 = sc; + sc->wmistat_open_pid = 0; + sc->wmistat_bufptr = -1; + ret = 0; + } + ACPI_SERIAL_END(acpi_wmi); + + return (ret); +} + +/* + * Detach the driver by: + * - Removing notification handler + * - Removing address space handler + * - Turning off event generation for all WExx event activated by + * child drivers + */ +static int +acpi_wmi_detach(device_t dev) +{ + struct wmi_info *winfo, *tmp; + struct acpi_wmi_softc *sc; + int ret; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + sc = device_get_softc(dev); + ACPI_SERIAL_BEGIN(acpi_wmi); + + if (sc->wmistat_open_pid != 0) { + ret = EBUSY; + } else { + AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, + acpi_wmi_notify_handler); + AcpiRemoveAddressSpaceHandler(sc->wmi_handle, + ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler); + TAILQ_FOREACH_SAFE(winfo, &wmi_info_list, wmi_list, tmp) { + if (winfo->event_handler) + acpi_wmi_toggle_we_event_generation(dev, + winfo, EVENT_GENERATION_OFF); + TAILQ_REMOVE(&wmi_info_list, winfo, wmi_list); + free(winfo, M_ACPIWMI); + } + if (sc->wmistat_bufptr != -1) { + sbuf_delete(&sc->wmistat_sbuf); + sc->wmistat_bufptr = -1; + } + sc->wmistat_open_pid = 0; + destroy_dev(sc->wmistat_dev_t); + ret = 0; + } + ACPI_SERIAL_END(acpi_wmi); + + return (ret); +} + + +/* + * Check if the given GUID string (human readable format + * AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP) + * exists within _WDG + */ +static int +acpi_wmi_provides_guid_string_method(device_t dev, const char *guid_string) +{ + int ret; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + ACPI_SERIAL_BEGIN(acpi_wmi); + ret = (acpi_wmi_lookup_wmi_info_by_guid_string(guid_string) == NULL)?0:1; + ACPI_SERIAL_END(acpi_wmi); + + return (ret); +} + +/* + * Call a method "method_id" on the given GUID block + * write result into user provided output buffer + */ +static ACPI_STATUS +acpi_wmi_evaluate_call_method(device_t dev, const char *guid_string, + UINT8 instance, UINT32 method_id, const ACPI_BUFFER *in, ACPI_BUFFER *out) +{ + ACPI_OBJECT params[3]; + ACPI_OBJECT_LIST input; + char method[5] = "WMxx"; + struct wmi_info *winfo; + struct acpi_wmi_softc *sc; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + ACPI_SERIAL_BEGIN(acpi_wmi); + if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + == NULL) + status = AE_NOT_FOUND; + else if (!(winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) + status = AE_BAD_DATA; + else if (instance > winfo->ginfo.max_instance) + status = AE_BAD_PARAMETER; + else { + params[0].Type = ACPI_TYPE_INTEGER; + params[0].Integer.Value = instance; + params[1].Type = ACPI_TYPE_INTEGER; + params[1].Integer.Value = method_id; + input.Pointer = params; + input.Count = 2; + if (in) { + params[2].Type = + (winfo->ginfo.flags & ACPI_WMI_REGFLAG_STRING) + ?ACPI_TYPE_STRING:ACPI_TYPE_BUFFER; + params[2].Buffer.Length = in->Length; + params[2].Buffer.Pointer = in->Pointer; + input.Count = 3; + } + method[2] = winfo->ginfo.oid[0]; + method[3] = winfo->ginfo.oid[1]; + status = AcpiEvaluateObject(sc->wmi_handle, method, + &input, out); + } + ACPI_SERIAL_END(acpi_wmi); + + return (status); +} + +/* + * Install a user provided event_handler on the given GUID + * provided *data will be passed on callback + * If there is already an existing event handler registered it will be silently + * discarded + */ +static ACPI_STATUS +acpi_wmi_install_event_handler_method(device_t dev, const char *guid_string, + ACPI_NOTIFY_HANDLER event_handler, void *data) +{ + struct wmi_info *winfo; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + status = AE_OK; + ACPI_SERIAL_BEGIN(acpi_wmi); + if (guid_string == NULL || event_handler == NULL) + status = AE_BAD_PARAMETER; + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + == NULL) + status = AE_NOT_EXIST; + else if (winfo->event_handler != NULL || + (status = acpi_wmi_toggle_we_event_generation(dev, winfo, + EVENT_GENERATION_ON)) == AE_OK) { + winfo->event_handler = event_handler; + winfo->event_handler_user_data = data; + } + ACPI_SERIAL_END(acpi_wmi); + + return (status); +} + +/* + * Remove a previously installed event handler from the given GUID + * If there was none installed, this call is silently discarded and + * reported as AE_OK + */ +static ACPI_STATUS +acpi_wmi_remove_event_handler_method(device_t dev, const char *guid_string) +{ + struct wmi_info *winfo; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + status = AE_OK; + ACPI_SERIAL_BEGIN(acpi_wmi); + if (guid_string && + (winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + != NULL && winfo->event_handler) { + status = acpi_wmi_toggle_we_event_generation(dev, winfo, + EVENT_GENERATION_OFF); + winfo->event_handler = NULL; + winfo->event_handler_user_data = NULL; + } + ACPI_SERIAL_END(acpi_wmi); + + return (status); +} + +/* + * Get details on an event received through a callback registered + * through ACPI_WMI_REMOVE_EVENT_HANDLER into a user provided output buffer. + * (event_id equals "notify" passed in the callback) + */ +static ACPI_STATUS +acpi_wmi_get_event_data_method(device_t dev, UINT32 event_id, ACPI_BUFFER *out) +{ + ACPI_OBJECT_LIST input; + ACPI_OBJECT params[1]; + struct acpi_wmi_softc *sc; + struct wmi_info *winfo; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + status = AE_NOT_FOUND; + ACPI_SERIAL_BEGIN(acpi_wmi); + params[0].Type = ACPI_TYPE_INTEGER; + params[0].Integer.Value = event_id; + input.Pointer = params; + input.Count = 1; + TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) && + ((UINT8) winfo->ginfo.oid[0] == event_id)) { + status = AcpiEvaluateObject(sc->wmi_handle, "_WED", + &input, out); + break; + } + } + ACPI_SERIAL_END(acpi_wmi); + + return (status); +} + +/* + * Read a block of data from the given GUID (using WQxx (query)) + * Will be returned in a user provided buffer (out). + * If the method is marked as expensive (ACPI_WMI_REGFLAG_EXPENSIVE) + * we will first call the WCxx control method to lock the node to + * lock the node for data collection and release it afterwards. + * (Failed WCxx calls are ignored to "support" broken implementations) + */ +static ACPI_STATUS +acpi_wmi_get_block_method(device_t dev, const char *guid_string, UINT8 instance, + ACPI_BUFFER *out) +{ + char wc_method[5] = "WCxx"; + char wq_method[5] = "WQxx"; + ACPI_OBJECT_LIST wc_input; + ACPI_OBJECT_LIST wq_input; + ACPI_OBJECT wc_params[1]; + ACPI_OBJECT wq_params[1]; + ACPI_HANDLE wc_handle; + struct acpi_wmi_softc *sc; + struct wmi_info *winfo; + ACPI_STATUS status; + ACPI_STATUS wc_status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + wc_status = AE_ERROR; + ACPI_SERIAL_BEGIN(acpi_wmi); + if (guid_string == NULL || out == NULL) + status = AE_BAD_PARAMETER; + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + == NULL) + status = AE_ERROR; + else if (instance > winfo->ginfo.max_instance) + status = AE_BAD_PARAMETER; + else if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) || + (winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) + status = AE_ERROR; + else { + wq_params[0].Type = ACPI_TYPE_INTEGER; + wq_params[0].Integer.Value = instance; + wq_input.Pointer = wq_params; + wq_input.Count = 1; + if (winfo->ginfo.flags & ACPI_WMI_REGFLAG_EXPENSIVE) { + wc_params[0].Type = ACPI_TYPE_INTEGER; + wc_params[0].Integer.Value = 1; + wc_input.Pointer = wc_params; + wc_input.Count = 1; + wc_method[2] = winfo->ginfo.oid[0]; + wc_method[3] = winfo->ginfo.oid[1]; + wc_status = AcpiGetHandle(sc->wmi_handle, wc_method, + &wc_handle); + if (ACPI_SUCCESS(wc_status)) + wc_status = AcpiEvaluateObject(wc_handle, + wc_method, &wc_input, NULL); + } + wq_method[2] = winfo->ginfo.oid[0]; + wq_method[3] = winfo->ginfo.oid[1]; + status = AcpiEvaluateObject(sc->wmi_handle, wq_method, + &wq_input, out); + if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EXPENSIVE) + && ACPI_SUCCESS(wc_status)) { + wc_params[0].Integer.Value = 0; + status = AcpiEvaluateObject(wc_handle, wc_method, + &wc_input, NULL); /* XXX this might be + the wrong status to + return? */ + } + } + ACPI_SERIAL_END(acpi_wmi); + + return (status); +} + +/* + * Write a block of data to the given GUID (using WSxx) + */ +static ACPI_STATUS +acpi_wmi_set_block_method(device_t dev, const char *guid_string, UINT8 instance, + const ACPI_BUFFER *in) +{ + char method[5] = "WSxx"; + ACPI_OBJECT_LIST input; + ACPI_OBJECT params[2]; + struct wmi_info *winfo; + struct acpi_wmi_softc *sc; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + ACPI_SERIAL_BEGIN(acpi_wmi); + if (guid_string == NULL || in == NULL) + status = AE_BAD_DATA; + else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) + == NULL) + status = AE_ERROR; + else if (instance > winfo->ginfo.max_instance) + status = AE_BAD_PARAMETER; + else if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) || + (winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) + status = AE_ERROR; + else { + params[0].Type = ACPI_TYPE_INTEGER; + params[0].Integer.Value = instance; + input.Pointer = params; + input.Count = 2; + params[1].Type = (winfo->ginfo.flags & ACPI_WMI_REGFLAG_STRING) + ?ACPI_TYPE_STRING:ACPI_TYPE_BUFFER; + params[1].Buffer.Length = in->Length; + params[1].Buffer.Pointer = in->Pointer; + method[2] = winfo->ginfo.oid[0]; + method[3] = winfo->ginfo.oid[1]; + status = AcpiEvaluateObject(sc->wmi_handle, method, + &input, NULL); + } + ACPI_SERIAL_END(acpi_wmi); + + return (status); +} + +/* + * Handle events received and dispatch them to + * stakeholders that registered through ACPI_WMI_INSTALL_EVENT_HANDLER + */ +static void +acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) +{ + ACPI_NOTIFY_HANDLER handler; + void *handler_data; + struct wmi_info *winfo; + + ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); + + handler = NULL; + handler_data = NULL; + ACPI_SERIAL_BEGIN(acpi_wmi); + TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) && + ((UINT8) winfo->ginfo.oid[0] == notify)) { + if (winfo->event_handler) { + handler = winfo->event_handler; + handler_data = winfo->event_handler_user_data; + break; + } + } + } + ACPI_SERIAL_END(acpi_wmi); + if (handler) { + handler(h, notify, handler_data); + } +} + +/* + * Handle EC address space notifications reveived on the WDG node + * (this mimics EcAddressSpaceHandler in acpi_ec.c) + */ +static ACPI_STATUS +acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, + UINT32 width, ACPI_INTEGER *value, void *context, + void *region_context) +{ + struct acpi_wmi_softc *sc; + int i; + ACPI_INTEGER ec_data; + UINT8 ec_addr; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Address); + + sc = (struct acpi_wmi_softc *)context; + if (width % 8 != 0 || value == NULL || context == NULL) + return (AE_BAD_PARAMETER); + if (address + (width / 8) - 1 > 0xFF) + return (AE_BAD_ADDRESS); + if (function == ACPI_READ) + *value = 0; + ec_addr = address; + status = AE_ERROR; + + for (i = 0; i < width; i += 8, ++ec_addr) { + switch (function) { + case ACPI_READ: + status = ACPI_EC_READ(sc->ec_dev, ec_addr, &ec_data, 1); + if (ACPI_SUCCESS(status)) + *value |= ((ACPI_INTEGER)ec_data) << i; + break; + case ACPI_WRITE: + ec_data = (UINT8)((*value) >> i); + status = ACPI_EC_WRITE(sc->ec_dev, ec_addr, ec_data, 1); + break; + default: + device_printf(sc->wmi_dev, + "invalid acpi_wmi_ec_handler function %d\n", + function); + status = AE_BAD_PARAMETER; + break; + } + if (ACPI_FAILURE(status)) + break; + } + + return (status); +} + +/* + * Read GUID blocks from the _WDG node + * into wmi_info_list. + */ +static ACPI_STATUS +acpi_wmi_read_wdg_blocks(ACPI_HANDLE h) +{ + ACPI_BUFFER out = {ACPI_ALLOCATE_BUFFER, NULL}; + struct guid_info *ginfo; + ACPI_OBJECT *obj; + struct wmi_info *winfo; + UINT32 i; + UINT32 wdg_block_count; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + ACPI_SERIAL_ASSERT(acpi_wmi); + if (ACPI_FAILURE(status = AcpiEvaluateObject(h, "_WDG", NULL, &out))) + return (status); + obj = (ACPI_OBJECT*) out.Pointer; + wdg_block_count = obj->Buffer.Length / sizeof(struct guid_info); + if ((ginfo = malloc(obj->Buffer.Length, M_ACPIWMI, M_NOWAIT)) + == NULL) { + AcpiOsFree(out.Pointer); + return (AE_NO_MEMORY); + } + memcpy(ginfo, obj->Buffer.Pointer, obj->Buffer.Length); + for (i = 0; i < wdg_block_count; ++i) { + if ((winfo = malloc(sizeof(struct wmi_info), M_ACPIWMI, + M_NOWAIT | M_ZERO)) == NULL) { + AcpiOsFree(out.Pointer); + free(ginfo, M_ACPIWMI); + return (AE_NO_MEMORY); + } + winfo->ginfo = ginfo[i]; + TAILQ_INSERT_TAIL(&wmi_info_list, winfo, wmi_list); + } + AcpiOsFree(out.Pointer); + free(ginfo, M_ACPIWMI); + + return (status); +} + +/* + * Toggle event generation in for the given GUID (passed by winfo) + * Turn on to get notified (through acpi_wmi_notify_handler) if events happen + * on the given GUID. + */ +static ACPI_STATUS +acpi_wmi_toggle_we_event_generation(device_t dev, struct wmi_info *winfo, + enum event_generation_state state) +{ + char method[5] = "WExx"; + ACPI_OBJECT_LIST input; + ACPI_OBJECT params[1]; + struct acpi_wmi_softc *sc; + ACPI_STATUS status; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + sc = device_get_softc(dev); + ACPI_SERIAL_ASSERT(acpi_wmi); + params[0].Type = ACPI_TYPE_INTEGER; + params[0].Integer.Value = state==EVENT_GENERATION_ON?1:0; + input.Pointer = params; + input.Count = 1; + + UINT8 hi = ((UINT8) winfo->ginfo.oid[0]) >> 4; + UINT8 lo = ((UINT8) winfo->ginfo.oid[0]) & 0xf; + method[2] = (hi > 9 ? hi + 55: hi + 48); + method[3] = (lo > 9 ? lo + 55: lo + 48); + status = AcpiEvaluateObject(sc->wmi_handle, method, &input, NULL); + if (status == AE_NOT_FOUND) status = AE_OK; + + return (status); +} + +/* + * Convert given two digit hex string (hexin) to an UINT8 referenced + * by byteout. + * Return != 0 if the was a problem (invalid input) + */ +static __inline int acpi_wmi_hex_to_int(const UINT8 *hexin, UINT8 *byteout) +{ + unsigned int hi; + unsigned int lo; + + hi = hexin[0]; + lo = hexin[1]; + if ('0' <= hi && hi <= '9') + hi -= '0'; + else if ('A' <= hi && hi <= 'F') + hi -= ('A' - 10); + else if ('a' <= hi && hi <= 'f') + hi -= ('a' - 10); + else + return (1); + if ('0' <= lo && lo <= '9') + lo -= '0'; + else if ('A' <= lo && lo <= 'F') + lo -= ('A' - 10); + else if ('a' <= lo && lo <= 'f') + lo -= ('a' - 10); + else + return (1); + *byteout = (hi << 4) + lo; + + return (0); +} + +/* + * Convert a human readable 36 character GUID into a 16byte + * machine readable one. + * The basic algorithm looks as follows: + * Input: AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP + * Output: DCBAFEHGIJKLMNOP + * (AA BB CC etc. represent two digit hex numbers == bytes) + * Return != 0 if passed guid string is invalid + */ +static int +acpi_wmi_guid_string_to_guid(const UINT8 *guid_string, UINT8 *guid) +{ + static const int mapping[20] = {3, 2, 1, 0, -1, 5, 4, -1, 7, 6, -1, + 8, 9, -1, 10, 11, 12, 13, 14, 15}; + int i; + + for (i = 0; i < 20; ++i, ++guid_string) { + if (mapping[i] >= 0) { + if (acpi_wmi_hex_to_int(guid_string, + &guid[mapping[i]])) + return (-1); + ++guid_string; + } else if (*guid_string != '-') + return (-1); + } + + return (0); +} + +/* + * Lookup a wmi_info structure in wmi_list based on a + * human readable GUID + * Return NULL if the GUID is unknown in the _WDG + */ +static struct wmi_info* +acpi_wmi_lookup_wmi_info_by_guid_string(const char *guid_string) +{ + char guid[16]; + struct wmi_info *winfo; + + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + + ACPI_SERIAL_ASSERT(acpi_wmi); + + if (!acpi_wmi_guid_string_to_guid(guid_string, guid)) { + TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + if (!memcmp(winfo->ginfo.guid, guid, 16)) { + return (winfo); + } + } + } + + return (NULL); +} + +/* + * open wmistat device + */ +static int +acpi_wmi_wmistat_open(struct cdev* dev, int flags, int mode, struct thread *td) +{ + struct acpi_wmi_softc *sc; + int ret; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(acpi_wmi); + if (sc->wmistat_open_pid != 0) { + ret = EBUSY; + } + else { + if (sbuf_new(&sc->wmistat_sbuf, NULL, 4096, SBUF_AUTOEXTEND) + == NULL) { + ret = ENXIO; + } else { + sc->wmistat_open_pid = td->td_proc->p_pid; + sc->wmistat_bufptr = 0; + ret = 0; + } + } + ACPI_SERIAL_END(acpi_wmi); + + return (ret); +} + +/* + * close wmistat device + */ +static int +acpi_wmi_wmistat_close(struct cdev* dev, int flags, int mode, + struct thread *td) +{ + struct acpi_wmi_softc *sc; + int ret; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(acpi_wmi); + if (sc->wmistat_open_pid == 0) { + ret = EBADF; + } + else { + if (sc->wmistat_bufptr != -1) { + sbuf_delete(&sc->wmistat_sbuf); + sc->wmistat_bufptr = -1; + } + sc->wmistat_open_pid = 0; + ret = 0; + } + ACPI_SERIAL_END(acpi_wmi); + + return (ret); +} + +/* + * Read from wmistat guid information + */ +static int +acpi_wmi_wmistat_read(struct cdev *dev, struct uio *buf, int flag) +{ + struct acpi_wmi_softc *sc; + struct wmi_info *winfo; + int l; + int ret; + UINT8* guid; + + if (dev == NULL || dev->si_drv1 == NULL) + return (EBADF); + sc = dev->si_drv1; + + ACPI_SERIAL_BEGIN(acpi_wmi); + if (sc->wmistat_open_pid != buf->uio_td->td_proc->p_pid || + sc->wmistat_bufptr == -1) { + ret = EBADF; + } + else { + if (!sbuf_done(&sc->wmistat_sbuf)) { + sbuf_printf(&sc->wmistat_sbuf, "GUID " + " INST EXPE METH STR " + "EVENT OID\n"); + TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { + guid = (UINT8*)winfo->ginfo.guid; + sbuf_printf(&sc->wmistat_sbuf, + "{%02X%02X%02X%02X-%02X%02X-" + "%02X%02X-%02X%02X-%02X%02X" + "%02X%02X%02X%02X} %3d %-5s", + guid[3], guid[2], guid[1], guid[0], + guid[5], guid[4], + guid[7], guid[6], + guid[8], guid[9], + guid[10], guid[11], guid[12], + guid[13], guid[14], guid[15], + winfo->ginfo.max_instance, + (winfo->ginfo.flags& + ACPI_WMI_REGFLAG_EXPENSIVE)? + "YES":"NO" + ); + if (winfo->ginfo.flags&ACPI_WMI_REGFLAG_METHOD) + sbuf_printf(&sc->wmistat_sbuf, + "WM%c%c ", + winfo->ginfo.oid[0], + winfo->ginfo.oid[1]); + else + sbuf_printf(&sc->wmistat_sbuf, "NO "); + sbuf_printf(&sc->wmistat_sbuf, "%-4s", + (winfo->ginfo.flags& + ACPI_WMI_REGFLAG_STRING)?"YES":"NO" + ); + if (winfo->ginfo.flags&ACPI_WMI_REGFLAG_EVENT) + sbuf_printf(&sc->wmistat_sbuf, + "0x%02X%s -\n", + (UINT8)winfo->ginfo.oid[0], + winfo->event_handler==NULL? + " ":"+"); + else + sbuf_printf(&sc->wmistat_sbuf, + "NO %c%c\n", + winfo->ginfo.oid[0], + winfo->ginfo.oid[1]); + } + sbuf_finish(&sc->wmistat_sbuf); + } + if (sbuf_len(&sc->wmistat_sbuf) <= 0) { + sbuf_delete(&sc->wmistat_sbuf); + sc->wmistat_bufptr = -1; + sc->wmistat_open_pid = 0; + ret = ENOMEM; + } else { + l = min(buf->uio_resid, sbuf_len(&sc->wmistat_sbuf) - + sc->wmistat_bufptr); + ret = (l > 0)?uiomove(sbuf_data(&sc->wmistat_sbuf) + + sc->wmistat_bufptr, l, buf) : 0; + sc->wmistat_bufptr += l; + } + } + ACPI_SERIAL_END(acpi_wmi); + + return (ret); +} --- sys/dev/acpi_support/acpi_wmi_if.m~ 2009-06-21 12:09:58.000000000 +0200 +++ sys/dev/acpi_support/acpi_wmi_if.m 2009-06-21 12:13:23.546375847 +0200 @@ -0,0 +1,144 @@ +#- +# Copyright (c) 2009 Michael Gmelin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD: src/sys/dev/acpic_support/acpi_wmi_if.m,v 1.0 2008/11/23 16:33:00 rmg Exp $ +# + +#include +#include +#include + +INTERFACE acpi_wmi; + +# +# Default implementation for acpi_wmi_generic_provides_guid_string(). +# +CODE { + static int + acpi_wmi_generic_provides_guid_string(device_t dev, const char* guid_string) + { + return 0; + } +}; + + +# +# Check if given GUID exists in WMI +# +# device_t dev: Device to probe +# const char* guid_string: String form of the GUID +# +METHOD int provides_guid_string { + device_t dev; + const char* guid_string; +} DEFAULT acpi_wmi_generic_provides_guid_string; + +# +# Evaluate a WMI method call +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# UINT8 instance: instance id +# UINT32 method_id: method to call +# const ACPI_BUFFER* in: input data +# ACPI_BUFFER* out: output buffer +# +METHOD ACPI_STATUS evaluate_call { + device_t dev; + const char *guid_string; + UINT8 instance; + UINT32 method_id; + const ACPI_BUFFER *in; + ACPI_BUFFER *out; +}; + +# +# Get content of a WMI block +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# UINT8 instance: instance id +# ACPI_BUFFER* out: output buffer +# +METHOD ACPI_STATUS get_block { + device_t dev; + const char *guid_string; + UINT8 instance; + ACPI_BUFFER *out; +}; +# +# Write to a WMI data block +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# UINT8 instance: instance id +# const ACPI_BUFFER* in: input data +# +METHOD ACPI_STATUS set_block { + device_t dev; + const char *guid_string; + UINT8 instance; + const ACPI_BUFFER *in; +}; + +# +# Install wmi event handler +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# ACPI_NOTIFY_HANDLER handler: Handler +# void* data: Payload +# +METHOD ACPI_STATUS install_event_handler { + device_t dev; + const char *guid_string; + ACPI_NOTIFY_HANDLER handler; + void *data; +}; + +# +# Remove wmi event handler +# +# device_t dev: Device to use +# const char* guid_string: String form of the GUID +# +METHOD ACPI_STATUS remove_event_handler { + device_t dev; + const char *guid_string; +}; + + +# +# Get event data associated to an event +# +# device_t dev: Device to use +# UINT32 event_id: event id +# ACPI_BUFFER* out: output buffer +# +METHOD ACPI_STATUS get_event_data { + device_t dev; + UINT32 event_id; + ACPI_BUFFER *out; +}; --- sys/modules/acpi/acpi_hp/Makefile~ 2009-06-21 12:09:58.000000000 +0200 +++ sys/modules/acpi/acpi_hp/Makefile 2009-06-21 12:10:33.000000000 +0100 @@ -0,0 +1,9 @@ +# $FreeBSD: src/sys/modules/acpi/acpi_hp/Makefile,v 1.3 2004/12/13 04:59:35 imp Exp $ + +.PATH: ${.CURDIR}/../../../dev/acpi_support +KMOD= acpi_hp +CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica +SRCS= acpi_hp.c opt_acpi.h device_if.h bus_if.h acpi_if.h acpi_wmi_if.h +SRCS+= opt_ddb.h + +.include --- sys/modules/acpi/acpi_wmi/Makefile~ 2009-06-21 12:09:58.000000000 +0200 +++ sys/modules/acpi/acpi_wmi/Makefile 2009-06-21 12:10:39.000000000 +0100 @@ -0,0 +1,10 @@ +# $FreeBSD: src/sys/modules/acpi/acpi_wmi/Makefile,v 1.7 2007/06/24 20:36:51 njl Exp $ + +.PATH: ${.CURDIR}/../../../dev/acpi_support + +KMOD= acpi_wmi +CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica +SRCS= acpi_wmi.c +SRCS+= opt_acpi.h acpi_if.h bus_if.h device_if.h acpi_wmi_if.h + +.include --- sys/conf/files.i386~ 2008-12-29 04:46:14.000000000 +0100 +++ sys/conf/files.i386 2009-06-21 12:10:14.000000000 +0100 @@ -226,6 +226,7 @@ dev/syscons/scvtb.c optional sc dev/uart/uart_cpu_i386.c optional uart dev/acpica/acpi_if.m standard +dev/acpi_support/acpi_wmi_if.m standard dev/wpi/if_wpi.c optional wpi i386/acpica/OsdEnvironment.c optional acpi i386/acpica/acpi_machdep.c optional acpi --- sys/conf/files~ 2008-12-29 04:45:44.000000000 +0100 +++ sys/conf/files 2009-06-21 12:10:44.000000000 +0100 @@ -375,9 +375,11 @@ dev/aac/aac_disk.c optional aac dev/aac/aac_linux.c optional aac compat_linux dev/aac/aac_pci.c optional aac pci +dev/acpi_support/acpi_wmi.c optional acpi_wmi acpi dev/acpi_support/acpi_aiboost.c optional acpi_aiboost acpi dev/acpi_support/acpi_asus.c optional acpi_asus acpi dev/acpi_support/acpi_fujitsu.c optional acpi_fujitsu acpi +dev/acpi_support/acpi_hp.c optional acpi_hp acpi dev/acpi_support/acpi_ibm.c optional acpi_ibm acpi dev/acpi_support/acpi_panasonic.c optional acpi_panasonic acpi dev/acpi_support/acpi_sony.c optional acpi_sony acpi --- sys/conf/kmod.mk~ 2008-12-29 04:44:41.000000000 +0100 +++ sys/conf/kmod.mk 2009-06-21 12:10:41.000000000 +0100 @@ -321,7 +321,7 @@ .endfor .endif -MFILES?= dev/acpica/acpi_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \ +MFILES?= dev/acpica/acpi_if.m dev/acpi_support/acpi_wmi_if.m dev/agp/agp_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \ dev/iicbus/iicbb_if.m dev/iicbus/iicbus_if.m \ dev/mmc/mmcbr_if.m dev/mmc/mmcbus_if.m \ dev/mii/miibus_if.m dev/ofw/ofw_bus_if.m \ --- share/man/man4/man4.i386/Makefile~ 2009-06-21 12:36:50.000000000 +0200 +++ share/man/man4/man4.i386/Makefile 2009-06-21 12:36:50.000000000 +0200 @@ -3,10 +3,12 @@ MAN= acpi_aiboost.4 \ acpi_asus.4 \ acpi_fujitsu.4 \ + acpi_hp.4 \ acpi_ibm.4 \ acpi_panasonic.4 \ acpi_sony.4 \ acpi_toshiba.4 \ + acpi_wmi.4 \ aic.4 \ alpm.4 \ amdpm.4 \ --------------000302080806090206000000 Content-Type: text/plain; name="acpi_wmi.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="acpi_wmi.c" /*- * Copyright (c) 2009 Michael Gmelin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); /* * Driver for acpi-wmi mapping, provides an interface for vendor specific * implementations (e.g. HP and Acer laptops). * Inspired by the ACPI-WMI mapping driver (c) 2008-2008 Carlos Corbacho which * implements this functionality for Linux. * * WMI and ACPI: http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx * acpi-wmi for Linux: http://www.kernel.org */ #include "opt_acpi.h" #include #include #include #include #include #include #include #include #include #include #include #include "acpi_wmi_if.h" MALLOC_DEFINE(M_ACPIWMI, "acpiwmi", "ACPI-WMI mapping"); #define _COMPONENT ACPI_OEM ACPI_MODULE_NAME("ACPI_WMI"); #define ACPI_WMI_REGFLAG_EXPENSIVE 0x1 /* GUID flag: Expensive operation */ #define ACPI_WMI_REGFLAG_METHOD 0x2 /* GUID flag: Method call */ #define ACPI_WMI_REGFLAG_STRING 0x4 /* GUID flag: String */ #define ACPI_WMI_REGFLAG_EVENT 0x8 /* GUID flag: Event */ /* * acpi_wmi driver private structure */ struct acpi_wmi_softc { device_t wmi_dev; /* wmi device id */ ACPI_HANDLE wmi_handle; /* handle of the PNP0C14 node */ device_t ec_dev; /* acpi_ec0 */ struct cdev *wmistat_dev_t; /* wmistat device handle */ struct sbuf wmistat_sbuf; /* sbuf for /dev/wmistat output */ pid_t wmistat_open_pid; /* pid operating on /dev/wmistat */ int wmistat_bufptr; /* /dev/wmistat ptr to buffer position */ }; /* * Struct that holds information about * about a single GUID entry in _WDG */ struct guid_info { char guid[16]; /* 16 byte non human readable GUID */ char oid[2]; /* object id or event notify id (first byte) */ UINT8 max_instance; /* highest instance known for this GUID */ UINT8 flags; /* ACPI_WMI_REGFLAG_%s */ }; /* WExx event generation state (on/off) */ enum event_generation_state { EVENT_GENERATION_ON = 1, EVENT_GENERATION_OFF = 0 }; /* * Information about one entry in _WDG. * List of those is used to lookup information by GUID. */ struct wmi_info { TAILQ_ENTRY(wmi_info) wmi_list; struct guid_info ginfo; /* information on guid */ ACPI_NOTIFY_HANDLER event_handler;/* client provided event handler */ void *event_handler_user_data; /* ev handler cookie */ }; TAILQ_HEAD(wmi_info_list_head, wmi_info) wmi_info_list = TAILQ_HEAD_INITIALIZER(wmi_info_list); ACPI_SERIAL_DECL(acpi_wmi, "ACPI-WMI Mapping"); /* public interface - declaration */ /* standard device interface*/ static int acpi_wmi_probe(device_t dev); static int acpi_wmi_attach(device_t dev); static int acpi_wmi_detach(device_t dev); /* see acpi_wmi_if.m */ static int acpi_wmi_provides_guid_string_method(device_t dev, const char *guid_string); static ACPI_STATUS acpi_wmi_evaluate_call_method(device_t dev, const char *guid_string, UINT8 instance, UINT32 method_id, const ACPI_BUFFER *in, ACPI_BUFFER *out); static ACPI_STATUS acpi_wmi_install_event_handler_method(device_t dev, const char *guid_string, ACPI_NOTIFY_HANDLER handler, void *data); static ACPI_STATUS acpi_wmi_remove_event_handler_method(device_t dev, const char *guid_string); static ACPI_STATUS acpi_wmi_get_event_data_method(device_t dev, UINT32 event_id, ACPI_BUFFER *out); static ACPI_STATUS acpi_wmi_get_block_method(device_t dev, const char *guid_string, UINT8 instance, ACPI_BUFFER *out); static ACPI_STATUS acpi_wmi_set_block_method(device_t dev, const char *guid_string, UINT8 instance, const ACPI_BUFFER *in); /* private interface - declaration */ /* callbacks */ static void acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context); static ACPI_STATUS acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, UINT32 width, ACPI_INTEGER *value, void *context, void *region_context); /* helpers */ static ACPI_STATUS acpi_wmi_read_wdg_blocks(ACPI_HANDLE h); static ACPI_STATUS acpi_wmi_toggle_we_event_generation(device_t dev, struct wmi_info *winfo, enum event_generation_state state); static int acpi_wmi_guid_string_to_guid(const UINT8 *guid_string, UINT8 *guid); static struct wmi_info* acpi_wmi_lookup_wmi_info_by_guid_string( const char *guid_string); static d_open_t acpi_wmi_wmistat_open; static d_close_t acpi_wmi_wmistat_close; static d_read_t acpi_wmi_wmistat_read; /* handler /dev/wmistat device */ static struct cdevsw wmistat_cdevsw = { .d_version = D_VERSION, .d_open = acpi_wmi_wmistat_open, .d_close = acpi_wmi_wmistat_close, .d_read = acpi_wmi_wmistat_read, .d_name = "wmistat", }; static device_method_t acpi_wmi_methods[] = { /* Device interface */ DEVMETHOD(device_probe, acpi_wmi_probe), DEVMETHOD(device_attach, acpi_wmi_attach), DEVMETHOD(device_detach, acpi_wmi_detach), /* acpi_wmi interface */ DEVMETHOD(acpi_wmi_provides_guid_string, acpi_wmi_provides_guid_string_method), DEVMETHOD(acpi_wmi_evaluate_call, acpi_wmi_evaluate_call_method), DEVMETHOD(acpi_wmi_install_event_handler, acpi_wmi_install_event_handler_method), DEVMETHOD(acpi_wmi_remove_event_handler, acpi_wmi_remove_event_handler_method), DEVMETHOD(acpi_wmi_get_event_data, acpi_wmi_get_event_data_method), DEVMETHOD(acpi_wmi_get_block, acpi_wmi_get_block_method), DEVMETHOD(acpi_wmi_set_block, acpi_wmi_set_block_method), {0, 0} }; static driver_t acpi_wmi_driver = { "acpi_wmi", acpi_wmi_methods, sizeof(struct acpi_wmi_softc), }; static devclass_t acpi_wmi_devclass; DRIVER_MODULE(acpi_wmi, acpi, acpi_wmi_driver, acpi_wmi_devclass, 0, 0); MODULE_VERSION(acpi_wmi, 1); MODULE_DEPEND(acpi_wmi, acpi, 1, 1, 1); static char *wmi_ids[] = {"PNP0C14", "PNP0c14", NULL}; /* * Probe for the PNP0C14 ACPI node */ static int acpi_wmi_probe(device_t dev) { if (acpi_disabled("wmi") || ACPI_ID_PROBE(device_get_parent(dev), dev, wmi_ids) == NULL) return (ENXIO); device_set_desc(dev, "ACPI-WMI mapping"); return (0); } /* * Attach the device by: * - Looking for the first ACPI EC device * - Install the notify handler * - Install the EC address space handler * - Look for the _WDG node and read GUID information blocks */ static int acpi_wmi_attach(device_t dev) { struct acpi_wmi_softc *sc; int ret; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); ret = ENXIO; ACPI_SERIAL_BEGIN(acpi_wmi); sc->wmi_dev = dev; sc->wmi_handle = acpi_get_handle(dev); TAILQ_INIT(&wmi_info_list); /* XXX Only works with one EC, but nearly all systems only have one. */ if ((sc->ec_dev = devclass_get_device(devclass_find("acpi_ec"), 0)) == NULL) device_printf(dev, "cannot find EC device\n"); else if (ACPI_FAILURE((status = AcpiInstallNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler, sc)))) device_printf(sc->wmi_dev, "couldn't install notify handler - %s\n", AcpiFormatException(status)); else if (ACPI_FAILURE((status = AcpiInstallAddressSpaceHandler( sc->wmi_handle, ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler, NULL, sc)))) { device_printf(sc->wmi_dev, "couldn't install EC handler - %s\n", AcpiFormatException(status)); AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler); } else if (ACPI_FAILURE((status = acpi_wmi_read_wdg_blocks( sc->wmi_handle)))) { device_printf(sc->wmi_dev, "couldn't parse _WDG - %s\n", AcpiFormatException(status)); AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler); AcpiRemoveAddressSpaceHandler(sc->wmi_handle, ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler); } else { sc->wmistat_dev_t = make_dev(&wmistat_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "wmistat"); sc->wmistat_dev_t->si_drv1 = sc; sc->wmistat_open_pid = 0; sc->wmistat_bufptr = -1; ret = 0; } ACPI_SERIAL_END(acpi_wmi); return (ret); } /* * Detach the driver by: * - Removing notification handler * - Removing address space handler * - Turning off event generation for all WExx event activated by * child drivers */ static int acpi_wmi_detach(device_t dev) { struct wmi_info *winfo, *tmp; struct acpi_wmi_softc *sc; int ret; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); ACPI_SERIAL_BEGIN(acpi_wmi); if (sc->wmistat_open_pid != 0) { ret = EBUSY; } else { AcpiRemoveNotifyHandler(sc->wmi_handle, ACPI_DEVICE_NOTIFY, acpi_wmi_notify_handler); AcpiRemoveAddressSpaceHandler(sc->wmi_handle, ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler); TAILQ_FOREACH_SAFE(winfo, &wmi_info_list, wmi_list, tmp) { if (winfo->event_handler) acpi_wmi_toggle_we_event_generation(dev, winfo, EVENT_GENERATION_OFF); TAILQ_REMOVE(&wmi_info_list, winfo, wmi_list); free(winfo, M_ACPIWMI); } if (sc->wmistat_bufptr != -1) { sbuf_delete(&sc->wmistat_sbuf); sc->wmistat_bufptr = -1; } sc->wmistat_open_pid = 0; destroy_dev(sc->wmistat_dev_t); ret = 0; } ACPI_SERIAL_END(acpi_wmi); return (ret); } /* * Check if the given GUID string (human readable format * AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP) * exists within _WDG */ static int acpi_wmi_provides_guid_string_method(device_t dev, const char *guid_string) { int ret; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_BEGIN(acpi_wmi); ret = (acpi_wmi_lookup_wmi_info_by_guid_string(guid_string) == NULL)?0:1; ACPI_SERIAL_END(acpi_wmi); return (ret); } /* * Call a method "method_id" on the given GUID block * write result into user provided output buffer */ static ACPI_STATUS acpi_wmi_evaluate_call_method(device_t dev, const char *guid_string, UINT8 instance, UINT32 method_id, const ACPI_BUFFER *in, ACPI_BUFFER *out) { ACPI_OBJECT params[3]; ACPI_OBJECT_LIST input; char method[5] = "WMxx"; struct wmi_info *winfo; struct acpi_wmi_softc *sc; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); ACPI_SERIAL_BEGIN(acpi_wmi); if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) == NULL) status = AE_NOT_FOUND; else if (!(winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) status = AE_BAD_DATA; else if (instance > winfo->ginfo.max_instance) status = AE_BAD_PARAMETER; else { params[0].Type = ACPI_TYPE_INTEGER; params[0].Integer.Value = instance; params[1].Type = ACPI_TYPE_INTEGER; params[1].Integer.Value = method_id; input.Pointer = params; input.Count = 2; if (in) { params[2].Type = (winfo->ginfo.flags & ACPI_WMI_REGFLAG_STRING) ?ACPI_TYPE_STRING:ACPI_TYPE_BUFFER; params[2].Buffer.Length = in->Length; params[2].Buffer.Pointer = in->Pointer; input.Count = 3; } method[2] = winfo->ginfo.oid[0]; method[3] = winfo->ginfo.oid[1]; status = AcpiEvaluateObject(sc->wmi_handle, method, &input, out); } ACPI_SERIAL_END(acpi_wmi); return (status); } /* * Install a user provided event_handler on the given GUID * provided *data will be passed on callback * If there is already an existing event handler registered it will be silently * discarded */ static ACPI_STATUS acpi_wmi_install_event_handler_method(device_t dev, const char *guid_string, ACPI_NOTIFY_HANDLER event_handler, void *data) { struct wmi_info *winfo; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); status = AE_OK; ACPI_SERIAL_BEGIN(acpi_wmi); if (guid_string == NULL || event_handler == NULL) status = AE_BAD_PARAMETER; else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) == NULL) status = AE_NOT_EXIST; else if (winfo->event_handler != NULL || (status = acpi_wmi_toggle_we_event_generation(dev, winfo, EVENT_GENERATION_ON)) == AE_OK) { winfo->event_handler = event_handler; winfo->event_handler_user_data = data; } ACPI_SERIAL_END(acpi_wmi); return (status); } /* * Remove a previously installed event handler from the given GUID * If there was none installed, this call is silently discarded and * reported as AE_OK */ static ACPI_STATUS acpi_wmi_remove_event_handler_method(device_t dev, const char *guid_string) { struct wmi_info *winfo; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); status = AE_OK; ACPI_SERIAL_BEGIN(acpi_wmi); if (guid_string && (winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) != NULL && winfo->event_handler) { status = acpi_wmi_toggle_we_event_generation(dev, winfo, EVENT_GENERATION_OFF); winfo->event_handler = NULL; winfo->event_handler_user_data = NULL; } ACPI_SERIAL_END(acpi_wmi); return (status); } /* * Get details on an event received through a callback registered * through ACPI_WMI_REMOVE_EVENT_HANDLER into a user provided output buffer. * (event_id equals "notify" passed in the callback) */ static ACPI_STATUS acpi_wmi_get_event_data_method(device_t dev, UINT32 event_id, ACPI_BUFFER *out) { ACPI_OBJECT_LIST input; ACPI_OBJECT params[1]; struct acpi_wmi_softc *sc; struct wmi_info *winfo; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); status = AE_NOT_FOUND; ACPI_SERIAL_BEGIN(acpi_wmi); params[0].Type = ACPI_TYPE_INTEGER; params[0].Integer.Value = event_id; input.Pointer = params; input.Count = 1; TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) && ((UINT8) winfo->ginfo.oid[0] == event_id)) { status = AcpiEvaluateObject(sc->wmi_handle, "_WED", &input, out); break; } } ACPI_SERIAL_END(acpi_wmi); return (status); } /* * Read a block of data from the given GUID (using WQxx (query)) * Will be returned in a user provided buffer (out). * If the method is marked as expensive (ACPI_WMI_REGFLAG_EXPENSIVE) * we will first call the WCxx control method to lock the node to * lock the node for data collection and release it afterwards. * (Failed WCxx calls are ignored to "support" broken implementations) */ static ACPI_STATUS acpi_wmi_get_block_method(device_t dev, const char *guid_string, UINT8 instance, ACPI_BUFFER *out) { char wc_method[5] = "WCxx"; char wq_method[5] = "WQxx"; ACPI_OBJECT_LIST wc_input; ACPI_OBJECT_LIST wq_input; ACPI_OBJECT wc_params[1]; ACPI_OBJECT wq_params[1]; ACPI_HANDLE wc_handle; struct acpi_wmi_softc *sc; struct wmi_info *winfo; ACPI_STATUS status; ACPI_STATUS wc_status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); wc_status = AE_ERROR; ACPI_SERIAL_BEGIN(acpi_wmi); if (guid_string == NULL || out == NULL) status = AE_BAD_PARAMETER; else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) == NULL) status = AE_ERROR; else if (instance > winfo->ginfo.max_instance) status = AE_BAD_PARAMETER; else if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) || (winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) status = AE_ERROR; else { wq_params[0].Type = ACPI_TYPE_INTEGER; wq_params[0].Integer.Value = instance; wq_input.Pointer = wq_params; wq_input.Count = 1; if (winfo->ginfo.flags & ACPI_WMI_REGFLAG_EXPENSIVE) { wc_params[0].Type = ACPI_TYPE_INTEGER; wc_params[0].Integer.Value = 1; wc_input.Pointer = wc_params; wc_input.Count = 1; wc_method[2] = winfo->ginfo.oid[0]; wc_method[3] = winfo->ginfo.oid[1]; wc_status = AcpiGetHandle(sc->wmi_handle, wc_method, &wc_handle); if (ACPI_SUCCESS(wc_status)) wc_status = AcpiEvaluateObject(wc_handle, wc_method, &wc_input, NULL); } wq_method[2] = winfo->ginfo.oid[0]; wq_method[3] = winfo->ginfo.oid[1]; status = AcpiEvaluateObject(sc->wmi_handle, wq_method, &wq_input, out); if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { wc_params[0].Integer.Value = 0; status = AcpiEvaluateObject(wc_handle, wc_method, &wc_input, NULL); /* XXX this might be the wrong status to return? */ } } ACPI_SERIAL_END(acpi_wmi); return (status); } /* * Write a block of data to the given GUID (using WSxx) */ static ACPI_STATUS acpi_wmi_set_block_method(device_t dev, const char *guid_string, UINT8 instance, const ACPI_BUFFER *in) { char method[5] = "WSxx"; ACPI_OBJECT_LIST input; ACPI_OBJECT params[2]; struct wmi_info *winfo; struct acpi_wmi_softc *sc; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); ACPI_SERIAL_BEGIN(acpi_wmi); if (guid_string == NULL || in == NULL) status = AE_BAD_DATA; else if ((winfo = acpi_wmi_lookup_wmi_info_by_guid_string(guid_string)) == NULL) status = AE_ERROR; else if (instance > winfo->ginfo.max_instance) status = AE_BAD_PARAMETER; else if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) || (winfo->ginfo.flags & ACPI_WMI_REGFLAG_METHOD)) status = AE_ERROR; else { params[0].Type = ACPI_TYPE_INTEGER; params[0].Integer.Value = instance; input.Pointer = params; input.Count = 2; params[1].Type = (winfo->ginfo.flags & ACPI_WMI_REGFLAG_STRING) ?ACPI_TYPE_STRING:ACPI_TYPE_BUFFER; params[1].Buffer.Length = in->Length; params[1].Buffer.Pointer = in->Pointer; method[2] = winfo->ginfo.oid[0]; method[3] = winfo->ginfo.oid[1]; status = AcpiEvaluateObject(sc->wmi_handle, method, &input, NULL); } ACPI_SERIAL_END(acpi_wmi); return (status); } /* * Handle events received and dispatch them to * stakeholders that registered through ACPI_WMI_INSTALL_EVENT_HANDLER */ static void acpi_wmi_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) { ACPI_NOTIFY_HANDLER handler; void *handler_data; struct wmi_info *winfo; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); handler = NULL; handler_data = NULL; ACPI_SERIAL_BEGIN(acpi_wmi); TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { if ((winfo->ginfo.flags & ACPI_WMI_REGFLAG_EVENT) && ((UINT8) winfo->ginfo.oid[0] == notify)) { if (winfo->event_handler) { handler = winfo->event_handler; handler_data = winfo->event_handler_user_data; break; } } } ACPI_SERIAL_END(acpi_wmi); if (handler) { handler(h, notify, handler_data); } } /* * Handle EC address space notifications reveived on the WDG node * (this mimics EcAddressSpaceHandler in acpi_ec.c) */ static ACPI_STATUS acpi_wmi_ec_handler(UINT32 function, ACPI_PHYSICAL_ADDRESS address, UINT32 width, ACPI_INTEGER *value, void *context, void *region_context) { struct acpi_wmi_softc *sc; int i; ACPI_INTEGER ec_data; UINT8 ec_addr; ACPI_STATUS status; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Address); sc = (struct acpi_wmi_softc *)context; if (width % 8 != 0 || value == NULL || context == NULL) return (AE_BAD_PARAMETER); if (address + (width / 8) - 1 > 0xFF) return (AE_BAD_ADDRESS); if (function == ACPI_READ) *value = 0; ec_addr = address; status = AE_ERROR; for (i = 0; i < width; i += 8, ++ec_addr) { switch (function) { case ACPI_READ: status = ACPI_EC_READ(sc->ec_dev, ec_addr, &ec_data, 1); if (ACPI_SUCCESS(status)) *value |= ((ACPI_INTEGER)ec_data) << i; break; case ACPI_WRITE: ec_data = (UINT8)((*value) >> i); status = ACPI_EC_WRITE(sc->ec_dev, ec_addr, ec_data, 1); break; default: device_printf(sc->wmi_dev, "invalid acpi_wmi_ec_handler function %d\n", function); status = AE_BAD_PARAMETER; break; } if (ACPI_FAILURE(status)) break; } return (status); } /* * Read GUID blocks from the _WDG node * into wmi_info_list. */ static ACPI_STATUS acpi_wmi_read_wdg_blocks(ACPI_HANDLE h) { ACPI_BUFFER out = {ACPI_ALLOCATE_BUFFER, NULL}; struct guid_info *ginfo; ACPI_OBJECT *obj; struct wmi_info *winfo; UINT32 i; UINT32 wdg_block_count; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_ASSERT(acpi_wmi); if (ACPI_FAILURE(status = AcpiEvaluateObject(h, "_WDG", NULL, &out))) return (status); obj = (ACPI_OBJECT*) out.Pointer; wdg_block_count = obj->Buffer.Length / sizeof(struct guid_info); if ((ginfo = malloc(obj->Buffer.Length, M_ACPIWMI, M_NOWAIT)) == NULL) { AcpiOsFree(out.Pointer); return (AE_NO_MEMORY); } memcpy(ginfo, obj->Buffer.Pointer, obj->Buffer.Length); for (i = 0; i < wdg_block_count; ++i) { if ((winfo = malloc(sizeof(struct wmi_info), M_ACPIWMI, M_NOWAIT | M_ZERO)) == NULL) { AcpiOsFree(out.Pointer); free(ginfo, M_ACPIWMI); return (AE_NO_MEMORY); } winfo->ginfo = ginfo[i]; TAILQ_INSERT_TAIL(&wmi_info_list, winfo, wmi_list); } AcpiOsFree(out.Pointer); free(ginfo, M_ACPIWMI); return (status); } /* * Toggle event generation in for the given GUID (passed by winfo) * Turn on to get notified (through acpi_wmi_notify_handler) if events happen * on the given GUID. */ static ACPI_STATUS acpi_wmi_toggle_we_event_generation(device_t dev, struct wmi_info *winfo, enum event_generation_state state) { char method[5] = "WExx"; ACPI_OBJECT_LIST input; ACPI_OBJECT params[1]; struct acpi_wmi_softc *sc; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); ACPI_SERIAL_ASSERT(acpi_wmi); params[0].Type = ACPI_TYPE_INTEGER; params[0].Integer.Value = state==EVENT_GENERATION_ON?1:0; input.Pointer = params; input.Count = 1; UINT8 hi = ((UINT8) winfo->ginfo.oid[0]) >> 4; UINT8 lo = ((UINT8) winfo->ginfo.oid[0]) & 0xf; method[2] = (hi > 9 ? hi + 55: hi + 48); method[3] = (lo > 9 ? lo + 55: lo + 48); status = AcpiEvaluateObject(sc->wmi_handle, method, &input, NULL); if (status == AE_NOT_FOUND) status = AE_OK; return (status); } /* * Convert given two digit hex string (hexin) to an UINT8 referenced * by byteout. * Return != 0 if the was a problem (invalid input) */ static __inline int acpi_wmi_hex_to_int(const UINT8 *hexin, UINT8 *byteout) { unsigned int hi; unsigned int lo; hi = hexin[0]; lo = hexin[1]; if ('0' <= hi && hi <= '9') hi -= '0'; else if ('A' <= hi && hi <= 'F') hi -= ('A' - 10); else if ('a' <= hi && hi <= 'f') hi -= ('a' - 10); else return (1); if ('0' <= lo && lo <= '9') lo -= '0'; else if ('A' <= lo && lo <= 'F') lo -= ('A' - 10); else if ('a' <= lo && lo <= 'f') lo -= ('a' - 10); else return (1); *byteout = (hi << 4) + lo; return (0); } /* * Convert a human readable 36 character GUID into a 16byte * machine readable one. * The basic algorithm looks as follows: * Input: AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP * Output: DCBAFEHGIJKLMNOP * (AA BB CC etc. represent two digit hex numbers == bytes) * Return != 0 if passed guid string is invalid */ static int acpi_wmi_guid_string_to_guid(const UINT8 *guid_string, UINT8 *guid) { static const int mapping[20] = {3, 2, 1, 0, -1, 5, 4, -1, 7, 6, -1, 8, 9, -1, 10, 11, 12, 13, 14, 15}; int i; for (i = 0; i < 20; ++i, ++guid_string) { if (mapping[i] >= 0) { if (acpi_wmi_hex_to_int(guid_string, &guid[mapping[i]])) return (-1); ++guid_string; } else if (*guid_string != '-') return (-1); } return (0); } /* * Lookup a wmi_info structure in wmi_list based on a * human readable GUID * Return NULL if the GUID is unknown in the _WDG */ static struct wmi_info* acpi_wmi_lookup_wmi_info_by_guid_string(const char *guid_string) { char guid[16]; struct wmi_info *winfo; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_ASSERT(acpi_wmi); if (!acpi_wmi_guid_string_to_guid(guid_string, guid)) { TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { if (!memcmp(winfo->ginfo.guid, guid, 16)) { return (winfo); } } } return (NULL); } /* * open wmistat device */ static int acpi_wmi_wmistat_open(struct cdev* dev, int flags, int mode, struct thread *td) { struct acpi_wmi_softc *sc; int ret; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(acpi_wmi); if (sc->wmistat_open_pid != 0) { ret = EBUSY; } else { if (sbuf_new(&sc->wmistat_sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) { ret = ENXIO; } else { sc->wmistat_open_pid = td->td_proc->p_pid; sc->wmistat_bufptr = 0; ret = 0; } } ACPI_SERIAL_END(acpi_wmi); return (ret); } /* * close wmistat device */ static int acpi_wmi_wmistat_close(struct cdev* dev, int flags, int mode, struct thread *td) { struct acpi_wmi_softc *sc; int ret; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(acpi_wmi); if (sc->wmistat_open_pid == 0) { ret = EBADF; } else { if (sc->wmistat_bufptr != -1) { sbuf_delete(&sc->wmistat_sbuf); sc->wmistat_bufptr = -1; } sc->wmistat_open_pid = 0; ret = 0; } ACPI_SERIAL_END(acpi_wmi); return (ret); } /* * Read from wmistat guid information */ static int acpi_wmi_wmistat_read(struct cdev *dev, struct uio *buf, int flag) { struct acpi_wmi_softc *sc; struct wmi_info *winfo; int l; int ret; UINT8* guid; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(acpi_wmi); if (sc->wmistat_open_pid != buf->uio_td->td_proc->p_pid || sc->wmistat_bufptr == -1) { ret = EBADF; } else { if (!sbuf_done(&sc->wmistat_sbuf)) { sbuf_printf(&sc->wmistat_sbuf, "GUID " " INST EXPE METH STR " "EVENT OID\n"); TAILQ_FOREACH(winfo, &wmi_info_list, wmi_list) { guid = (UINT8*)winfo->ginfo.guid; sbuf_printf(&sc->wmistat_sbuf, "{%02X%02X%02X%02X-%02X%02X-" "%02X%02X-%02X%02X-%02X%02X" "%02X%02X%02X%02X} %3d %-5s", guid[3], guid[2], guid[1], guid[0], guid[5], guid[4], guid[7], guid[6], guid[8], guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15], winfo->ginfo.max_instance, (winfo->ginfo.flags& ACPI_WMI_REGFLAG_EXPENSIVE)? "YES":"NO" ); if (winfo->ginfo.flags&ACPI_WMI_REGFLAG_METHOD) sbuf_printf(&sc->wmistat_sbuf, "WM%c%c ", winfo->ginfo.oid[0], winfo->ginfo.oid[1]); else sbuf_printf(&sc->wmistat_sbuf, "NO "); sbuf_printf(&sc->wmistat_sbuf, "%-4s", (winfo->ginfo.flags& ACPI_WMI_REGFLAG_STRING)?"YES":"NO" ); if (winfo->ginfo.flags&ACPI_WMI_REGFLAG_EVENT) sbuf_printf(&sc->wmistat_sbuf, "0x%02X%s -\n", (UINT8)winfo->ginfo.oid[0], winfo->event_handler==NULL? " ":"+"); else sbuf_printf(&sc->wmistat_sbuf, "NO %c%c\n", winfo->ginfo.oid[0], winfo->ginfo.oid[1]); } sbuf_finish(&sc->wmistat_sbuf); } if (sbuf_len(&sc->wmistat_sbuf) <= 0) { sbuf_delete(&sc->wmistat_sbuf); sc->wmistat_bufptr = -1; sc->wmistat_open_pid = 0; ret = ENOMEM; } else { l = min(buf->uio_resid, sbuf_len(&sc->wmistat_sbuf) - sc->wmistat_bufptr); ret = (l > 0)?uiomove(sbuf_data(&sc->wmistat_sbuf) + sc->wmistat_bufptr, l, buf) : 0; sc->wmistat_bufptr += l; } } ACPI_SERIAL_END(acpi_wmi); return (ret); } --------------000302080806090206000000 Content-Type: text/plain; name="acpi_hp.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="acpi_hp.c" /*- * Copyright (c) 2009 Michael Gmelin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); /* * Driver for extra ACPI-controlled features found on HP laptops * that use a WMI enabled BIOS (e.g. HP Compaq 8510p and 6510p). * Allows to control and read status of integrated hardware and read * BIOS settings through CMI. * Inspired by the hp-wmi driver, which implements a subset of these * features (hotkeys) on Linux. * * HP CMI whitepaper: * http://h20331.www2.hp.com/Hpsub/downloads/cmi_whitepaper.pdf * wmi-hp for Linux: * http://www.kernel.org * WMI and ACPI: * http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx */ #include "opt_acpi.h" #include #include #include #include #include #include #include #include #include #include #include #include "acpi_wmi_if.h" #define _COMPONENT ACPI_OEM ACPI_MODULE_NAME("HP") #define ACPI_HP_WMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" #define ACPI_HP_WMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" #define ACPI_HP_WMI_CMI_GUID "2D114B49-2DFB-4130-B8FE-4A3C09E75133" #define ACPI_HP_WMI_DISPLAY_COMMAND 0x1 #define ACPI_HP_WMI_HDDTEMP_COMMAND 0x2 #define ACPI_HP_WMI_ALS_COMMAND 0x3 #define ACPI_HP_WMI_DOCK_COMMAND 0x4 #define ACPI_HP_WMI_WIRELESS_COMMAND 0x5 #define ACPI_HP_METHOD_WLAN_ENABLED 1 #define ACPI_HP_METHOD_WLAN_RADIO 2 #define ACPI_HP_METHOD_WLAN_ON_AIR 3 #define ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON 4 #define ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF 5 #define ACPI_HP_METHOD_BLUETOOTH_ENABLED 6 #define ACPI_HP_METHOD_BLUETOOTH_RADIO 7 #define ACPI_HP_METHOD_BLUETOOTH_ON_AIR 8 #define ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON 9 #define ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF 10 #define ACPI_HP_METHOD_WWAN_ENABLED 11 #define ACPI_HP_METHOD_WWAN_RADIO 12 #define ACPI_HP_METHOD_WWAN_ON_AIR 13 #define ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON 14 #define ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF 15 #define ACPI_HP_METHOD_ALS 16 #define ACPI_HP_METHOD_DISPLAY 17 #define ACPI_HP_METHOD_HDDTEMP 18 #define ACPI_HP_METHOD_DOCK 19 #define ACPI_HP_METHOD_CMI_DETAIL 20 #define HP_MASK_WWAN_ON_AIR 0x1000000 #define HP_MASK_BLUETOOTH_ON_AIR 0x10000 #define HP_MASK_WLAN_ON_AIR 0x100 #define HP_MASK_WWAN_RADIO 0x8000000 #define HP_MASK_BLUETOOTH_RADIO 0x80000 #define HP_MASK_WLAN_RADIO 0x800 #define HP_MASK_WWAN_ENABLED 0x2000000 #define HP_MASK_BLUETOOTH_ENABLED 0x20000 #define HP_MASK_WLAN_ENABLED 0x200 #define ACPI_HP_CMI_DETAIL_PATHS 0x01 #define ACPI_HP_CMI_DETAIL_ENUMS 0x02 #define ACPI_HP_CMI_DETAIL_FLAGS 0x04 struct acpi_hp_inst_seq_pair { UINT32 sequence; /* sequence number as suggested by cmi bios */ UINT8 instance; /* object instance on guid */ }; struct acpi_hp_softc { device_t dev; ACPI_HANDLE handle; device_t wmi_dev; int has_notify; /* notification GUID found */ int has_cmi; /* CMI GUID found */ int cmi_detail; /* CMI detail level (set by sysctl) */ int wlan_enable_if_radio_on; /* set by sysctl */ int wlan_disable_if_radio_off; /* set by sysctl */ int bluetooth_enable_if_radio_on; /* set by sysctl */ int bluetooth_disable_if_radio_off; /* set by sysctl */ int wwan_enable_if_radio_on; /* set by sysctl */ int wwan_disable_if_radio_off; /* set by sysctl */ int was_wlan_on_air; /* last known WLAN on air status */ int was_bluetooth_on_air; /* last known BT on air status */ int was_wwan_on_air; /* last known WWAN on air status */ struct sysctl_ctx_list *sysctl_ctx; struct sysctl_oid *sysctl_tree; struct cdev *hpcmi_dev_t; /* hpcmi device handle */ struct sbuf hpcmi_sbuf; /* /dev/hpcmi output sbuf */ pid_t hpcmi_open_pid; /* pid operating on /dev/hpcmi */ int hpcmi_bufptr; /* current pointer position in /dev/hpcmi output buffer */ int cmi_order_size; /* size of cmi_order list */ struct acpi_hp_inst_seq_pair cmi_order[128]; /* list of CMI instances ordered by BIOS suggested sequence */ }; static struct { char *name; int method; char *description; int access; } acpi_hp_sysctls[] = { { .name = "wlan_enabled", .method = ACPI_HP_METHOD_WLAN_ENABLED, .description = "Enable/Disable WLAN (WiFi)", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wlan_radio", .method = ACPI_HP_METHOD_WLAN_RADIO, .description = "WLAN radio status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "wlan_on_air", .method = ACPI_HP_METHOD_WLAN_ON_AIR, .description = "WLAN radio ready to use (enabled and radio)", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "wlan_enable_if_radio_on", .method = ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON, .description = "Enable WLAN if radio is turned on", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wlan_disable_if_radio_off", .method = ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF, .description = "Disable WLAN if radio is turned off", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "bt_enabled", .method = ACPI_HP_METHOD_BLUETOOTH_ENABLED, .description = "Enable/Disable Bluetooth", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "bt_radio", .method = ACPI_HP_METHOD_BLUETOOTH_RADIO, .description = "Bluetooth radio status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "bt_on_air", .method = ACPI_HP_METHOD_BLUETOOTH_ON_AIR, .description = "Bluetooth radio ready to use" " (enabled and radio)", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "bt_enable_if_radio_on", .method = ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON, .description = "Enable bluetooth if radio is turned on", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "bt_disable_if_radio_off", .method = ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF, .description = "Disable bluetooth if radio is turned off", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wwan_enabled", .method = ACPI_HP_METHOD_WWAN_ENABLED, .description = "Enable/Disable WWAN (UMTS)", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wwan_radio", .method = ACPI_HP_METHOD_WWAN_RADIO, .description = "WWAN radio status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "wwan_on_air", .method = ACPI_HP_METHOD_WWAN_ON_AIR, .description = "WWAN radio ready to use (enabled and radio)", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "wwan_enable_if_radio_on", .method = ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON, .description = "Enable WWAN if radio is turned on", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wwan_disable_if_radio_off", .method = ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF, .description = "Disable WWAN if radio is turned off", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "als_enabled", .method = ACPI_HP_METHOD_ALS, .description = "Enable/Disable ALS (Ambient light sensor)", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "display", .method = ACPI_HP_METHOD_DISPLAY, .description = "Display status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "hdd_temperature", .method = ACPI_HP_METHOD_HDDTEMP, .description = "HDD temperature", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "is_docked", .method = ACPI_HP_METHOD_DOCK, .description = "Docking station status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "cmi_detail", .method = ACPI_HP_METHOD_CMI_DETAIL, .description = "Details shown in CMI output " "(cat /dev/hpcmi)", .access = CTLTYPE_INT | CTLFLAG_RW }, { NULL, 0, NULL, 0 } }; ACPI_SERIAL_DECL(hp, "HP ACPI-WMI Mapping"); static int acpi_hp_probe(device_t dev); static int acpi_hp_attach(device_t dev); static int acpi_hp_detach(device_t dev); static void acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc* sc); static int acpi_hp_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_hp_sysctl_set(struct acpi_hp_softc *sc, int method, int arg, int oldarg); static int acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method); static int acpi_hp_exec_wmi_command(device_t wmi_dev, int command, int is_write, int val); static void acpi_hp_notify(ACPI_HANDLE h, UINT32 notify, void *context); static int acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, UINT8 instance, char* outbuf, size_t outsize, UINT32* sequence, int detail); static void acpi_hp_hex_decode(char* buffer); static d_open_t acpi_hp_hpcmi_open; static d_close_t acpi_hp_hpcmi_close; static d_read_t acpi_hp_hpcmi_read; /* handler /dev/hpcmi device */ static struct cdevsw hpcmi_cdevsw = { .d_version = D_VERSION, .d_open = acpi_hp_hpcmi_open, .d_close = acpi_hp_hpcmi_close, .d_read = acpi_hp_hpcmi_read, .d_name = "hpcmi", }; static device_method_t acpi_hp_methods[] = { DEVMETHOD(device_probe, acpi_hp_probe), DEVMETHOD(device_attach, acpi_hp_attach), DEVMETHOD(device_detach, acpi_hp_detach), {0, 0} }; static driver_t acpi_hp_driver = { "acpi_hp", acpi_hp_methods, sizeof(struct acpi_hp_softc), }; static devclass_t acpi_hp_devclass; DRIVER_MODULE(acpi_hp, acpi, acpi_hp_driver, acpi_hp_devclass, 0, 0); MODULE_DEPEND(acpi_hp, acpi_wmi, 1, 1, 1); MODULE_DEPEND(acpi_hp, acpi, 1, 1, 1); static void acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc *sc) { int wireless; int new_wlan_status; int new_bluetooth_status; int new_wwan_status; wireless = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); new_wlan_status = -1; new_bluetooth_status = -1; new_wwan_status = -1; device_printf(sc->wmi_dev, "Wireless status is %x\n", wireless); if (sc->wlan_disable_if_radio_off && !(wireless & HP_MASK_WLAN_RADIO) && (wireless & HP_MASK_WLAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x100); new_wlan_status = 0; } else if (sc->wlan_enable_if_radio_on && (wireless & HP_MASK_WLAN_RADIO) && !(wireless & HP_MASK_WLAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x101); new_wlan_status = 1; } if (sc->bluetooth_disable_if_radio_off && !(wireless & HP_MASK_BLUETOOTH_RADIO) && (wireless & HP_MASK_BLUETOOTH_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x200); new_bluetooth_status = 0; } else if (sc->bluetooth_enable_if_radio_on && (wireless & HP_MASK_BLUETOOTH_RADIO) && !(wireless & HP_MASK_BLUETOOTH_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x202); new_bluetooth_status = 1; } if (sc->wwan_disable_if_radio_off && !(wireless & HP_MASK_WWAN_RADIO) && (wireless & HP_MASK_WWAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x400); new_wwan_status = 0; } else if (sc->wwan_enable_if_radio_on && (wireless & HP_MASK_WWAN_RADIO) && !(wireless & HP_MASK_WWAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x404); new_wwan_status = 1; } if (new_wlan_status == -1) { new_wlan_status = (wireless & HP_MASK_WLAN_ON_AIR); if ((new_wlan_status?1:0) != sc->was_wlan_on_air) { sc->was_wlan_on_air = sc->was_wlan_on_air?0:1; device_printf(sc->wmi_dev, "WLAN on air changed to %i " "(new_wlan_status is %i)\n", sc->was_wlan_on_air, new_wlan_status); acpi_UserNotify("HP", sc->handle, 0xc0+sc->was_wlan_on_air); } } if (new_bluetooth_status == -1) { new_bluetooth_status = (wireless & HP_MASK_BLUETOOTH_ON_AIR); if ((new_bluetooth_status?1:0) != sc->was_bluetooth_on_air) { sc->was_bluetooth_on_air = sc->was_bluetooth_on_air? 0:1; device_printf(sc->wmi_dev, "BLUETOOTH on air changed" " to %i (new_bluetooth_status is %i)\n", sc->was_bluetooth_on_air, new_bluetooth_status); acpi_UserNotify("HP", sc->handle, 0xd0+sc->was_bluetooth_on_air); } } if (new_wwan_status == -1) { new_wwan_status = (wireless & HP_MASK_WWAN_ON_AIR); if ((new_wwan_status?1:0) != sc->was_wwan_on_air) { sc->was_wwan_on_air = sc->was_wwan_on_air?0:1; device_printf(sc->wmi_dev, "WWAN on air changed to %i" " (new_wwan_status is %i)\n", sc->was_wwan_on_air, new_wwan_status); acpi_UserNotify("HP", sc->handle, 0xe0+sc->was_wwan_on_air); } } } static int acpi_hp_probe(device_t dev) { if (acpi_disabled("hp") || device_get_unit(dev) != 0) return (ENXIO); device_set_desc(dev, "HP ACPI-WMI Mapping"); return (0); } static int acpi_hp_attach(device_t dev) { struct acpi_hp_softc *sc; struct acpi_softc *acpi_sc; devclass_t wmi_devclass; int arg; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); sc = device_get_softc(dev); sc->dev = dev; sc->handle = acpi_get_handle(dev); sc->has_notify = 0; sc->has_cmi = 0; sc->bluetooth_enable_if_radio_on = 0; sc->bluetooth_disable_if_radio_off = 0; sc->wlan_enable_if_radio_on = 0; sc->wlan_disable_if_radio_off = 0; sc->wlan_enable_if_radio_on = 0; sc->wlan_disable_if_radio_off = 0; sc->was_wlan_on_air = 0; sc->was_bluetooth_on_air = 0; sc->was_wwan_on_air = 0; sc->cmi_detail = 0; sc->cmi_order_size = -1; memset(sc->cmi_order, 0, sizeof(sc->cmi_order)); acpi_sc = acpi_device_get_parent_softc(dev); if (!(wmi_devclass = devclass_find ("acpi_wmi"))) { device_printf(dev, "Couldn't find acpi_wmi devclass\n"); return (EINVAL); } if (!(sc->wmi_dev = devclass_get_device(wmi_devclass, 0))) { device_printf(dev, "Couldn't find acpi_wmi device\n"); return (EINVAL); } if (!ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_BIOS_GUID)) { device_printf(dev, "WMI device does not provide the HP BIOS GUID\n"); return (EINVAL); } if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_EVENT_GUID)) { device_printf(dev, "HP event GUID detected, installing event handler\n"); if (ACPI_WMI_INSTALL_EVENT_HANDLER(sc->wmi_dev, ACPI_HP_WMI_EVENT_GUID, acpi_hp_notify, dev)) { device_printf(dev, "Could not install notification handler!\n"); } else { sc->has_notify = 1; } } if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID)) { device_printf(dev, "HP CMI GUID detected\n"); sc->has_cmi = 1; } if (sc->has_cmi) { sc->hpcmi_dev_t = make_dev(&hpcmi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "hpcmi"); sc->hpcmi_dev_t->si_drv1 = sc; sc->hpcmi_open_pid = 0; sc->hpcmi_bufptr = -1; } ACPI_SERIAL_BEGIN(hp); sc->sysctl_ctx = device_get_sysctl_ctx(dev); sc->sysctl_tree = device_get_sysctl_tree(dev); for (int i = 0; acpi_hp_sysctls[i].name != NULL; ++i) { arg = 0; if ((!sc->has_notify && (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF)) || (arg = acpi_hp_sysctl_get(sc, acpi_hp_sysctls[i].method)) < 0) { continue; } if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_ON_AIR) { sc->was_wlan_on_air = arg; } else if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_ON_AIR) { sc->was_bluetooth_on_air = arg; } else if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_ON_AIR) { sc->was_wwan_on_air = arg; } SYSCTL_ADD_PROC(sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, acpi_hp_sysctls[i].name, acpi_hp_sysctls[i].access, sc, i, acpi_hp_sysctl, "I", acpi_hp_sysctls[i].description); } ACPI_SERIAL_END(hp); return (0); } static int acpi_hp_detach(device_t dev) { int ret; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); struct acpi_hp_softc *sc = device_get_softc(dev); if (sc->has_cmi && sc->hpcmi_open_pid != 0) { ret = EBUSY; } else { if (sc->has_notify) { ACPI_WMI_REMOVE_EVENT_HANDLER(dev, ACPI_HP_WMI_EVENT_GUID); } if (sc->hpcmi_bufptr != -1) { sbuf_delete(&sc->hpcmi_sbuf); sc->hpcmi_bufptr = -1; } sc->hpcmi_open_pid = 0; destroy_dev(sc->hpcmi_dev_t); ret = 0; } return (ret); } static int acpi_hp_sysctl(SYSCTL_HANDLER_ARGS) { struct acpi_hp_softc *sc; int arg; int oldarg; int error = 0; int function; int method; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = (struct acpi_hp_softc *)oidp->oid_arg1; function = oidp->oid_arg2; method = acpi_hp_sysctls[function].method; ACPI_SERIAL_BEGIN(hp); arg = acpi_hp_sysctl_get(sc, method); oldarg = arg; error = sysctl_handle_int(oidp, &arg, 0, req); if (!error && req->newptr != NULL) { error = acpi_hp_sysctl_set(sc, method, arg, oldarg); } ACPI_SERIAL_END(hp); return (error); } static int acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method) { int val = 0; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_ASSERT(hp); switch (method) { case ACPI_HP_METHOD_WLAN_ENABLED: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WLAN_ENABLED) != 0); break; case ACPI_HP_METHOD_WLAN_RADIO: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WLAN_RADIO) != 0); break; case ACPI_HP_METHOD_WLAN_ON_AIR: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WLAN_ON_AIR) != 0); break; case ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON: val = sc->wlan_enable_if_radio_on; break; case ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF: val = sc->wlan_disable_if_radio_off; break; case ACPI_HP_METHOD_BLUETOOTH_ENABLED: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_BLUETOOTH_ENABLED) != 0); break; case ACPI_HP_METHOD_BLUETOOTH_RADIO: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_BLUETOOTH_RADIO) != 0); break; case ACPI_HP_METHOD_BLUETOOTH_ON_AIR: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_BLUETOOTH_ON_AIR) != 0); break; case ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON: val = sc->bluetooth_enable_if_radio_on; break; case ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF: val = sc->bluetooth_disable_if_radio_off; break; case ACPI_HP_METHOD_WWAN_ENABLED: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WWAN_ENABLED) != 0); break; case ACPI_HP_METHOD_WWAN_RADIO: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WWAN_RADIO) != 0); break; case ACPI_HP_METHOD_WWAN_ON_AIR: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WWAN_ON_AIR) != 0); break; case ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON: val = sc->wwan_enable_if_radio_on; break; case ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF: val = sc->wwan_disable_if_radio_off; break; case ACPI_HP_METHOD_ALS: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_ALS_COMMAND, 0, 0); break; case ACPI_HP_METHOD_DISPLAY: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_DISPLAY_COMMAND, 0, 0); break; case ACPI_HP_METHOD_HDDTEMP: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_HDDTEMP_COMMAND, 0, 0); break; case ACPI_HP_METHOD_DOCK: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_DOCK_COMMAND, 0, 0); break; case ACPI_HP_METHOD_CMI_DETAIL: val = sc->cmi_detail; break; } return (val); } static int acpi_hp_sysctl_set(struct acpi_hp_softc *sc, int method, int arg, int oldarg) { ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_ASSERT(hp); if (method != ACPI_HP_METHOD_CMI_DETAIL) arg = arg?1:0; if (arg != oldarg) { switch (method) { case ACPI_HP_METHOD_WLAN_ENABLED: return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x101:0x100)); case ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON: sc->wlan_enable_if_radio_on = arg; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF: sc->wlan_disable_if_radio_off = arg; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_BLUETOOTH_ENABLED: return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x202:0x200)); case ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON: sc->bluetooth_enable_if_radio_on = arg; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF: sc->bluetooth_disable_if_radio_off = arg?1:0; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_WWAN_ENABLED: return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x404:0x400)); case ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON: sc->wwan_enable_if_radio_on = arg?1:0; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF: sc->wwan_disable_if_radio_off = arg?1:0; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_ALS: return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_ALS_COMMAND, 1, arg?1:0)); case ACPI_HP_METHOD_CMI_DETAIL: sc->cmi_detail = arg; break; } } return (0); } static __inline void acpi_hp_free_buffer(ACPI_BUFFER* buf) { if (buf && buf->Pointer) { AcpiOsFree(buf->Pointer); } } static void acpi_hp_notify(ACPI_HANDLE h, UINT32 notify, void *context) { device_t dev = context; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); struct acpi_hp_softc *sc = device_get_softc(dev); ACPI_BUFFER response = { ACPI_ALLOCATE_BUFFER, NULL }; ACPI_OBJECT *obj; ACPI_WMI_GET_EVENT_DATA(sc->wmi_dev, notify, &response); obj = (ACPI_OBJECT*) response.Pointer; if (obj && obj->Type == ACPI_TYPE_BUFFER && obj->Buffer.Length == 8) { if (*((UINT8 *) obj->Buffer.Pointer) == 0x5) { acpi_hp_evaluate_auto_on_off(sc); } } acpi_hp_free_buffer(&response); } static int acpi_hp_exec_wmi_command(device_t wmi_dev, int command, int is_write, int val) { UINT32 params[5] = { 0x55434553, is_write?2:1, command, is_write?4:0, val}; UINT32* result; ACPI_OBJECT *obj; ACPI_BUFFER in = { sizeof(params), ¶ms }; ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; int retval; if (ACPI_FAILURE(ACPI_WMI_EVALUATE_CALL(wmi_dev, ACPI_HP_WMI_BIOS_GUID, 0, 0x3, &in, &out))) { acpi_hp_free_buffer(&out); return (-EINVAL); } obj = out.Pointer; if (!obj || obj->Type != ACPI_TYPE_BUFFER) { acpi_hp_free_buffer(&out); return (-EINVAL); } result = (UINT32*) obj->Buffer.Pointer; retval = result[2]; if (result[1] > 0) { retval = result[1]; } acpi_hp_free_buffer(&out); return (retval); } static __inline char* acpi_hp_get_string_from_object(ACPI_OBJECT* obj, char* dst, size_t size) { int length; dst[0] = 0; if (obj->Type == ACPI_TYPE_STRING) { length = obj->String.Length+1; if (length > size) { length = size - 1; } strlcpy(dst, obj->String.Pointer, length); acpi_hp_hex_decode(dst); } return (dst); } /* * Read BIOS Setting block in instance "instance". * The block returned is ACPI_TYPE_PACKAGE which should contain the following * elements: * Index Meaning * 0 Setting Name [string] * 1 Value (comma separated, asterisk marks the current value) [string] * 2 Path within the bios hierarchy [string] * 3 IsReadOnly [int] * 4 DisplayInUI [int] * 5 RequiresPhysicalPresence [int] * 6 Sequence for ordering within the bios settings (absolute) [int] * 7 Length of prerequisites array [int] * 8 Prerequisite1 [string] * 9 Prerequisite2 [string] * 10 Prerequisite3 [string] * 11 Current value (in case of enum) [string] / Array length [int] * 12 Enum length [int] / Array values * 13ff Enum value at index x [string] */ static int acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, UINT8 instance, char* outbuf, size_t outsize, UINT32* sequence, int detail) { ACPI_OBJECT *obj; ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; int i; int outlen; int size = 255; int has_enums = 0; char string_buffer[size]; int enumbase; outlen = 0; outbuf[0] = 0; if (ACPI_FAILURE(ACPI_WMI_GET_BLOCK(wmi_dev, guid, instance, &out))) { acpi_hp_free_buffer(&out); return (-EINVAL); } obj = out.Pointer; if (!obj && obj->Type != ACPI_TYPE_PACKAGE) { acpi_hp_free_buffer(&out); return (-EINVAL); } /* check if this matches our expectations based on limited knowledge */ if (obj->Package.Count >= 13 && obj->Package.Elements[0].Type == ACPI_TYPE_STRING && obj->Package.Elements[1].Type == ACPI_TYPE_STRING && obj->Package.Elements[2].Type == ACPI_TYPE_STRING && obj->Package.Elements[3].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[4].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[5].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[6].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[7].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[8].Type == ACPI_TYPE_STRING && obj->Package.Elements[9].Type == ACPI_TYPE_STRING && obj->Package.Elements[10].Type == ACPI_TYPE_STRING && ((obj->Package.Elements[11].Type == ACPI_TYPE_STRING && obj->Package.Elements[12].Type == ACPI_TYPE_INTEGER && obj->Package.Count >= 13+obj->Package.Elements[12].Integer.Value) || (obj->Package.Elements[11].Type == ACPI_TYPE_INTEGER && obj->Package.Count >= 12+obj->Package.Elements[11].Integer.Value)) ) { enumbase = obj->Package.Elements[11].Type == ACPI_TYPE_STRING? 12:11; if (detail & ACPI_HP_CMI_DETAIL_PATHS) { strlcat(outbuf, acpi_hp_get_string_from_object( &obj->Package.Elements[2], string_buffer, size), outsize); outlen += 48; while (strlen(outbuf) < outlen) strlcat(outbuf, " ", outsize); } strlcat(outbuf, acpi_hp_get_string_from_object( &obj->Package.Elements[0], string_buffer, size), outsize); outlen += 43; while (strlen(outbuf) < outlen) strlcat(outbuf, " ", outsize); if (enumbase == 12) strlcat(outbuf, acpi_hp_get_string_from_object( &obj->Package.Elements[11], string_buffer, size), outsize); outlen += 21; while (strlen(outbuf) < outlen) strlcat(outbuf, " ", outsize); for (i = 0; i < strlen(outbuf); ++i) if (outbuf[i] == '\\') outbuf[i] = '/'; if (detail & ACPI_HP_CMI_DETAIL_ENUMS) { for (i = enumbase+1; i < enumbase + 1 + obj->Package.Elements[enumbase].Integer.Value; ++i) { acpi_hp_get_string_from_object( &obj->Package.Elements[i], string_buffer, size); if (strlen(string_buffer) > 1 || (strlen(string_buffer) == 1 && string_buffer[0] != ' ')) { if (has_enums) strlcat(outbuf, "/", outsize); else strlcat(outbuf, " (", outsize); strlcat(outbuf, string_buffer, outsize); has_enums = 1; } } } if (has_enums) strlcat(outbuf, ")", outsize); if (detail & ACPI_HP_CMI_DETAIL_FLAGS) { strlcat(outbuf, obj->Package.Elements[3].Integer.Value? " [ReadOnly]":"", outsize); strlcat(outbuf, obj->Package.Elements[4].Integer.Value? "":" [NOUI]", outsize); strlcat(outbuf, obj->Package.Elements[5].Integer.Value? " [RPP]":"", outsize); } *sequence = (UINT32) obj->Package.Elements[6].Integer.Value; } acpi_hp_free_buffer(&out); return (0); } /* * Convert given two digit hex string (hexin) to an UINT8 referenced * by byteout. * Return != 0 if the was a problem (invalid input) */ static __inline int acpi_hp_hex_to_int(const UINT8 *hexin, UINT8 *byteout) { unsigned int hi; unsigned int lo; hi = hexin[0]; lo = hexin[1]; if ('0' <= hi && hi <= '9') hi -= '0'; else if ('A' <= hi && hi <= 'F') hi -= ('A' - 10); else if ('a' <= hi && hi <= 'f') hi -= ('a' - 10); else return (1); if ('0' <= lo && lo <= '9') lo -= '0'; else if ('A' <= lo && lo <= 'F') lo -= ('A' - 10); else if ('a' <= lo && lo <= 'f') lo -= ('a' - 10); else return (1); *byteout = (hi << 4) + lo; return (0); } static void acpi_hp_hex_decode(char* buffer) { int i; int length = strlen(buffer); UINT8 *uin; UINT8 uout; if (((int)length/2)*2 == length || length < 10) return; for (i = 0; i= '0' && buffer[i] <= '9') || (buffer[i] >= 'A' && buffer[i] <= 'F'))) return; } for (i = 0; isi_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(hp); if (sc->hpcmi_open_pid != 0) { ret = EBUSY; } else { if (sbuf_new(&sc->hpcmi_sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) { ret = ENXIO; } else { sc->hpcmi_open_pid = td->td_proc->p_pid; sc->hpcmi_bufptr = 0; ret = 0; } } ACPI_SERIAL_END(hp); return (ret); } /* * close hpcmi device */ static int acpi_hp_hpcmi_close(struct cdev* dev, int flags, int mode, struct thread *td) { struct acpi_hp_softc *sc; int ret; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(hp); if (sc->hpcmi_open_pid == 0) { ret = EBADF; } else { if (sc->hpcmi_bufptr != -1) { sbuf_delete(&sc->hpcmi_sbuf); sc->hpcmi_bufptr = -1; } sc->hpcmi_open_pid = 0; ret = 0; } ACPI_SERIAL_END(hp); return (ret); } /* * Read from hpcmi bios information */ static int acpi_hp_hpcmi_read(struct cdev *dev, struct uio *buf, int flag) { struct acpi_hp_softc *sc; int pos, i, l, ret; UINT8 instance; UINT32 sequence; int linesize = 1025; char line[linesize]; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(hp); if (sc->hpcmi_open_pid != buf->uio_td->td_proc->p_pid || sc->hpcmi_bufptr == -1) { ret = EBADF; } else { if (!sbuf_done(&sc->hpcmi_sbuf)) { if (sc->cmi_order_size < 0) { sc->cmi_order_size = 0; for (instance = 0; instance < 128; ++instance) { if (acpi_hp_get_cmi_block(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID, instance, line, linesize, &sequence, sc->cmi_detail)) { instance = 128; } else { pos = sc->cmi_order_size; for (i=0; icmi_order_size && i<127; ++i) { if (sc->cmi_order[i].sequence > sequence) { pos = i; break; } } for (i=sc->cmi_order_size; i>pos; --i) { sc->cmi_order[i].sequence = sc->cmi_order[i-1].sequence; sc->cmi_order[i].instance = sc->cmi_order[i-1].instance; } sc->cmi_order[pos].sequence = sequence; sc->cmi_order[pos].instance = instance; sc->cmi_order_size++; } } } for (i=0; icmi_order_size; ++i) { if (!acpi_hp_get_cmi_block(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID, sc->cmi_order[i].instance, line, linesize, &sequence, sc->cmi_detail)) { sbuf_printf(&sc->hpcmi_sbuf, "%s\n", line); } } sbuf_finish(&sc->hpcmi_sbuf); } if (sbuf_len(&sc->hpcmi_sbuf) <= 0) { sbuf_delete(&sc->hpcmi_sbuf); sc->hpcmi_bufptr = -1; sc->hpcmi_open_pid = 0; ret = ENOMEM; } else { l = min(buf->uio_resid, sbuf_len(&sc->hpcmi_sbuf) - sc->hpcmi_bufptr); ret = (l > 0)?uiomove(sbuf_data(&sc->hpcmi_sbuf) + sc->hpcmi_bufptr, l, buf) : 0; sc->hpcmi_bufptr += l; } } ACPI_SERIAL_END(hp); return (ret); } --------------000302080806090206000000-- From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 16:56:21 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 517901065672 for ; Sun, 21 Jun 2009 16:56:21 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: from mail-ew0-f212.google.com (mail-ew0-f212.google.com [209.85.219.212]) by mx1.freebsd.org (Postfix) with ESMTP id CE4EC8FC0A for ; Sun, 21 Jun 2009 16:56:20 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: by ewy8 with SMTP id 8so3229962ewy.43 for ; Sun, 21 Jun 2009 09:56:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:cc:message-id:from:to :in-reply-to:content-type:content-transfer-encoding:mime-version :subject:date:references:x-mailer; bh=pn4AQHFMyammzATaxWTnGaK0fZ+FVYBNwX3eEXHRhrE=; b=KEspy/4qjf3mhzGDOOkXHvy7h4KMdYTNhT68wM3612RrKSmPAmgvlGY5e6pQA5gRpd 7iAfj6j2qjWI7Ob0yAHEM92DZy8bgrBN2CNQ2gQr7Uyp8otYWOsFrD7NsZqZ/otLuOaw hgkSeNmL+xxXJDdKOa32jn63hbTscTxqi2URg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:cc:message-id:from:to:in-reply-to:content-type :content-transfer-encoding:mime-version:subject:date:references :x-mailer; b=fYbBtMHPtdAIF//gRCSRleyM0/+hVpuB67q1dnKcj3hmkUifxra0XMCy74mPXhKkDi EjSHTL8jr3fE+vCEn7Dq/1XrT36GGfXAUUt67xRXHftDLKfAzDbwT4vbBlKS1NnlSm22 VG0LmXUBGdUzRu8y5GpChlSSRAD090ujwdGK8= Received: by 10.210.128.5 with SMTP id a5mr3580633ebd.85.1245603379747; Sun, 21 Jun 2009 09:56:19 -0700 (PDT) Received: from omega.lan (bl9-155-202.dsl.telepac.pt [85.242.155.202]) by mx.google.com with ESMTPS id 23sm3482398eya.49.2009.06.21.09.56.18 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 21 Jun 2009 09:56:19 -0700 (PDT) Sender: Rui Paulo Message-Id: From: Rui Paulo To: Michael In-Reply-To: <4A3E5F40.4040709@bindone.de> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v935.3) Date: Sun, 21 Jun 2009 17:56:17 +0100 References: <4A3E1784.2050406@bindone.de> <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> <4A3E5F40.4040709@bindone.de> X-Mailer: Apple Mail (2.935.3) Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 16:56:21 -0000 On 21 Jun 2009, at 17:26, Michael wrote: > Rui Paulo wrote: >> On 21 Jun 2009, at 15:08, Rui Paulo wrote: >> >>> On 21 Jun 2009, at 12:20, Michael wrote: >>> >>>> Hello, >>>> >>>> I wrote two new acpi modules last year and finally found the time >>>> to fix >>>> them, add some missing features and write man pages. >>> >>> Michael, this is great work! I'll review and see if we can ship it >>> with 8.0! >> >> Michael, this looks good, but there are two style nits that we need >> to fix. >> * we should try not going over the 80 column mark >> * add a empty new line before every return >> >> If you could send me a new patch for 8.0 with these fixes, I'll >> commit >> it (unless someone else has objections). >> >> Regards, >> -- >> Rui Paulo >> > > Hi Rui, > > hmm style(9) doesn't say anything about columns or return statements > in > this context (maybe it should be updated?!?). I've been looking again at style(9) and seems like I'm misremembering something. Please ignore this request and sorry for the hassle. -- Rui Paulo From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 17:03:06 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 62F48106564A for ; Sun, 21 Jun 2009 17:03:06 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 76C5B8FC1B for ; Sun, 21 Jun 2009 17:03:05 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 92627 invoked by uid 89); 21 Jun 2009 17:03:04 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.188.39) by mail.bindone.de with ESMTPA; 21 Jun 2009 17:03:04 -0000 Message-ID: <4A3E6796.4010501@bindone.de> Date: Sun, 21 Jun 2009 19:02:14 +0200 From: Michael User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: Rui Paulo References: <4A3E1784.2050406@bindone.de> <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> <4A3E6563.7040400@bindone.de> <8F2C596E-1B49-4E15-ACC0-84C1A14BD245@freebsd.org> In-Reply-To: <8F2C596E-1B49-4E15-ACC0-84C1A14BD245@freebsd.org> Content-Type: multipart/mixed; boundary="------------010608060309080501060308" Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 17:03:06 -0000 This is a multi-part message in MIME format. --------------010608060309080501060308 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Rui Paulo wrote: > On 21 Jun 2009, at 17:52, Michael wrote: > >> Rui Paulo wrote: >>> On 21 Jun 2009, at 15:08, Rui Paulo wrote: >>> >>>> On 21 Jun 2009, at 12:20, Michael wrote: >>>> >>>>> Hello, >>>>> >>>>> I wrote two new acpi modules last year and finally found the time >>>>> to fix >>>>> them, add some missing features and write man pages. >>>> >>>> Michael, this is great work! I'll review and see if we can ship it >>>> with 8.0! >>> >>> Michael, this looks good, but there are two style nits that we need >>> to fix. >>> * we should try not going over the 80 column mark >>> * add a empty new line before every return >>> >>> If you could send me a new patch for 8.0 with these fixes, I'll commit >>> it (unless someone else has objections). >>> >>> Regards, >>> -- >>> Rui Paulo >>> >> >> Hi Rui, >> >> I figured that adding newlines in conditional returns makes no sense >> (see my last post), so I did reformat everything to be (close to) 80 >> columns a line add added newlines in front of returns at the end of a >> function. > > Yeah, forget about the newlines before return. > >> Please find attached the complete patch again (against clean >> 7.2-RELEASE) and the files that changed (acpi_hp.c and acpi_wmi.c). > > Can you send it in MIME format or store it at some webserver so I could > fetch it? > >> Btw, what is the normal adoption path for 7-STABLE (I would assume first >> it gets into HEAD and if there's interest there will be a backport to 7? >> It should at least work in there, even so for HP laptops my guess is >> that most users will use 8 anyway because of wireless support). > > > It first goes into 8.0 and then 7-STABLE. > > Thanks, > -- > Rui Paulo > Hmm, that should have been MIME Format (are you using MacMail by any chance - seen issues there before..) I attached it again as an archive, does that work for you? cheers Michael --------------010608060309080501060308 Content-Type: application/octet-stream; name="files_for_rui.tgz" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="files_for_rui.tgz" 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 nz9//vz589/58/8BghQ/nwCYAwA= --------------010608060309080501060308-- From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 17:06:23 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 86248106566C for ; Sun, 21 Jun 2009 17:06:23 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: from ey-out-2122.google.com (ey-out-2122.google.com [74.125.78.27]) by mx1.freebsd.org (Postfix) with ESMTP id 0E85B8FC15 for ; Sun, 21 Jun 2009 17:06:22 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: by ey-out-2122.google.com with SMTP id 9so272248eyd.7 for ; Sun, 21 Jun 2009 10:06:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:cc:message-id:from:to :in-reply-to:content-type:content-transfer-encoding:mime-version :subject:date:references:x-mailer; bh=rGDHBDvQpdYTUWOkyqhljJNJFnshZnx0gG+4b4BagOo=; b=koPYQPjRyp41FqINdAY67KnufpYWvwBk/ZL6EVJXDBKCCk4KGPyiyciq+2Jees8aZe RBBeZpoTF/9ay0BW+tXtr5VCVoJ6l/wrUY/ugq30sRofknYboO+esGsYRapPd7PAscdQ LnBOLm0/z1hTfl62O1s+9NiUUAxZodvbYd9ZQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:cc:message-id:from:to:in-reply-to:content-type :content-transfer-encoding:mime-version:subject:date:references :x-mailer; b=O4kPouGIwVXNb9koXQMAIc8NxWpeFjUO6lt9ISiM/4urwZIrlhThRxk35GN7Uxa8Fi 1mnwzE0UmTy6hkZYvdenV+3xnphVco3KL9p2qFOQSuY4lYxlblUV8v1TWKZMBa5qmgyr Uj2SqQfqYPOu7Ex4+CycONPGO1EFf3Cnxyqc0= Received: by 10.210.42.20 with SMTP id p20mr6091943ebp.92.1245603578443; Sun, 21 Jun 2009 09:59:38 -0700 (PDT) Received: from omega.lan (bl9-155-202.dsl.telepac.pt [85.242.155.202]) by mx.google.com with ESMTPS id 24sm266437eyx.13.2009.06.21.09.59.37 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 21 Jun 2009 09:59:38 -0700 (PDT) Sender: Rui Paulo Message-Id: <8F2C596E-1B49-4E15-ACC0-84C1A14BD245@freebsd.org> From: Rui Paulo To: Michael In-Reply-To: <4A3E6563.7040400@bindone.de> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v935.3) Date: Sun, 21 Jun 2009 17:59:36 +0100 References: <4A3E1784.2050406@bindone.de> <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> <4A3E6563.7040400@bindone.de> X-Mailer: Apple Mail (2.935.3) Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 17:06:23 -0000 On 21 Jun 2009, at 17:52, Michael wrote: > Rui Paulo wrote: >> On 21 Jun 2009, at 15:08, Rui Paulo wrote: >> >>> On 21 Jun 2009, at 12:20, Michael wrote: >>> >>>> Hello, >>>> >>>> I wrote two new acpi modules last year and finally found the time >>>> to fix >>>> them, add some missing features and write man pages. >>> >>> Michael, this is great work! I'll review and see if we can ship it >>> with 8.0! >> >> Michael, this looks good, but there are two style nits that we need >> to fix. >> * we should try not going over the 80 column mark >> * add a empty new line before every return >> >> If you could send me a new patch for 8.0 with these fixes, I'll >> commit >> it (unless someone else has objections). >> >> Regards, >> -- >> Rui Paulo >> > > Hi Rui, > > I figured that adding newlines in conditional returns makes no sense > (see my last post), so I did reformat everything to be (close to) 80 > columns a line add added newlines in front of returns at the end of a > function. Yeah, forget about the newlines before return. > Please find attached the complete patch again (against clean > 7.2-RELEASE) and the files that changed (acpi_hp.c and acpi_wmi.c). Can you send it in MIME format or store it at some webserver so I could fetch it? > Btw, what is the normal adoption path for 7-STABLE (I would assume > first > it gets into HEAD and if there's interest there will be a backport > to 7? > It should at least work in there, even so for HP laptops my guess is > that most users will use 8 anyway because of wireless support). It first goes into 8.0 and then 7-STABLE. Thanks, -- Rui Paulo From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 17:50:15 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BC3731065672 for ; Sun, 21 Jun 2009 17:50:15 +0000 (UTC) (envelope-from robert.moore@intel.com) Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by mx1.freebsd.org (Postfix) with ESMTP id 943588FC1A for ; Sun, 21 Jun 2009 17:50:15 +0000 (UTC) (envelope-from robert.moore@intel.com) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 21 Jun 2009 10:50:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.42,263,1243839600"; d="scan'208";a="156911379" Received: from orsmsx604.amr.corp.intel.com ([10.22.226.87]) by azsmga001.ch.intel.com with ESMTP; 21 Jun 2009 10:50:14 -0700 Received: from orsmsx503.amr.corp.intel.com ([10.22.226.47]) by orsmsx604.amr.corp.intel.com ([10.250.113.17]) with mapi; Sun, 21 Jun 2009 10:50:14 -0700 From: "Moore, Robert" To: "hexanism@gmx.de" , "freebsd-acpi@freebsd.org" Date: Sun, 21 Jun 2009 10:50:13 -0700 Thread-Topic: Resume problem (Motherboard: MSI 790GX-G65) Thread-Index: AcnySjBT6cGDOQWWTXizllRLvPxKLQATVuhg Message-ID: <4911F71203A09E4D9981D27F9D8308582E8438B6@orsmsx503.amr.corp.intel.com> References: <4A3DEEFC.4010204@gmx.de> In-Reply-To: <4A3DEEFC.4010204@gmx.de> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Cc: Subject: RE: Resume problem (Motherboard: MSI 790GX-G65) X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 17:50:16 -0000 There are some nasty issues with this DSDT. Mainly, it uses "module-level" = executable code, which has been illegal since ACPI 2.0. The ACPICA interpre= ter does not support it, nor does the iASL compiler. Once all the instances of this type of code are commented out, the DSDT com= piles, although there are 17 warnings. Some of them are potentially serious= . Some examples: dsdt.dsl 3499: Release (MLMU) Warning 1099 - Statement is unreachable ^ dsdt.dsl 9069: Add (Local1, 0x80) Warning 1105 - ^ Result is not used, ope= rator has no effect dsdt.dsl 6167: Acquire (MUTE, 0x03E8) Warning 1104 - ^ Possible operator timeout= is ignored You probably should check if a new bios is available for this machine. Interesting, the MB is an MSI, but the DSDT contains this: Name (VEND, Buffer (0x05) { "ASUS" }) I will email you updated DSDT source and the output from the compiler. Bob >-----Original Message----- >From: owner-freebsd-acpi@freebsd.org [mailto:owner-freebsd- >acpi@freebsd.org] On Behalf Of hexanism@gmx.de >Sent: Sunday, June 21, 2009 1:28 AM >To: freebsd-acpi@freebsd.org >Subject: Resume problem (Motherboard: MSI 790GX-G65) > >Hello, > >I am using suspend/resume (S3) a lot in Linux. Unfortunately I could not >get it to work with FreeBSD. I wanted to solve the Problem by trying the >hints in the FreeBSD manual. I could not get it to work. Maybe someone >can point me in the right direction, I do not have any experience with >ACPI/dsdt debugging. > >The motherboard I am using is a MSI 790GX-G65 featuring the AMD 790 >Chipset. This model is quite a new AM3 board. It has an onboard >3D-accelerated AMD graphics card. The Bios is up to date (Revision 1.3). >I am using FreeBSD 7.2-RC2 with the generic kernel (I also did all >the testing with another hardrive using FreeBSD 7.2-RELEASE). > >Suspend and resume work with Linux (Ubuntu 9.04) and Windows XP 64 >flawlessly. > >S1 freezes the screen about two seconds after calling "acpiconf -s 1". >Then I have to press the reset button. S3/suspend seems to work. The >Fans and drives turn off and the power led acts exactly the same way as >it acts under Linux and Windows. Under Linux/Windows I can resume by >Keyboard. Under FreeBSD that does not work, I have to press the power >button to get the computer to react. Unfortunately the screen stays >black (drives and fans do get turned on). I have to press the reset button= . > >I inspected the dsdt of my motherboard: > >http://innoits.de/chris-msi790gx65.asl > >There are a lot of errors when recompiling with iasl (about 180 Errors, >most of them "Object does not exist"). I downloaded the ACPI >specifications (3.0a, 3.0b and 4.0) but could not fix the Errors (I >started with the first one ;)) due to my lack of knowledge concerning ACPI= . > >What can I do now? Most of the errors are of the same type. I hope that >ther is a simple solution that I just can't solve by myself. Is there a >good beginner friendly dsdt tutorial around? Is it possible that the >dsdt of my motherboard uses a newer ACPI revision (4.0) and thus is >incompatible with the current version of iasl? > >Thank you very much for reading this... > >Chris > From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 20:39:18 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id ED80E1065673 for ; Sun, 21 Jun 2009 20:39:18 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 4D1088FC0A for ; Sun, 21 Jun 2009 20:39:15 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 2666 invoked by uid 89); 21 Jun 2009 20:39:14 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.188.39) by mail.bindone.de with ESMTPA; 21 Jun 2009 20:39:14 -0000 Message-ID: <4A3E9A41.3070101@bindone.de> Date: Sun, 21 Jun 2009 22:38:25 +0200 From: Michael User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: Rui Paulo , freebsd-acpi@freebsd.org References: <4A3E1784.2050406@bindone.de> <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> <4A3E6563.7040400@bindone.de> <8F2C596E-1B49-4E15-ACC0-84C1A14BD245@freebsd.org> <4A3E6796.4010501@bindone.de> <4A3E7F85.8040309@bindone.de> <95927F48-2E42-4BD6-AB33-CC21D857AD84@freebsd.org> In-Reply-To: <95927F48-2E42-4BD6-AB33-CC21D857AD84@freebsd.org> Content-Type: multipart/mixed; boundary="------------030208030508040400030407" X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 20:39:20 -0000 This is a multi-part message in MIME format. --------------030208030508040400030407 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi Rui, please find attached a patchset set applies and compiles cleanly on HEAD of today (checked out approx. 2 hours ago). I also attached the patch for 7.2 again (so if somebody stumbles over this post they have both patches attached). I gziped them to avoid MUA madness. I also attached a tgz for the patches against HEAD, just in case. Changes done for HEAD are: - Modified kmod.mk patch (because of agp) - Modified includes in acpi_hp.c acpi_wmi.c and acpi_wmi_if.m because of changes caused by importing ACPICA 20090521 two weeks ago - Moved man pages to share/man/man4 (this is where all acpi_support man pages are in HEAD) - Fixed space-instead-of-tab issues in NOTES Install instructions: mkdir /usr/src/sys/modules/acpi/acpi_hp mkdir /usr/src/sys/modules/acpi/acpi_wmi patch -d /usr/src < acpi_wmi_and_acpi_hp_8.patch Maybe you can drop me a short note when it has been checked in (just for my own pleasure :) cheers Michael --------------030208030508040400030407-- From owner-freebsd-acpi@FreeBSD.ORG Sun Jun 21 23:20:51 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 368B3106566C for ; Sun, 21 Jun 2009 23:20:51 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: from mail-ew0-f212.google.com (mail-ew0-f212.google.com [209.85.219.212]) by mx1.freebsd.org (Postfix) with ESMTP id B22628FC12 for ; Sun, 21 Jun 2009 23:20:50 +0000 (UTC) (envelope-from rpaulo@gmail.com) Received: by ewy8 with SMTP id 8so3389858ewy.43 for ; Sun, 21 Jun 2009 16:20:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:cc:message-id:from:to :in-reply-to:content-type:content-transfer-encoding:mime-version :subject:date:references:x-mailer; bh=LbFDU0TZZMws80QKOK7YFIShNimNri3PysZaKcsJbww=; b=rVIY0/3Zbp0ayRWC3HaOMNHwFewLvc926v06UNyi3PzwKkKFqaOh2mLt3Q5nBBQ7/H COY6/szjlz9mZzLGECe3haGD5UjFvhRZnvenWZ0+iZU8r1hlIoiU2OxJXJvh8WWppTN+ lLlfcyrMegalGk3kdFDXGFAvQP6zMAws99Gzg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:cc:message-id:from:to:in-reply-to:content-type :content-transfer-encoding:mime-version:subject:date:references :x-mailer; b=Vc5gUEfNj0nEcq/DyWBYswQg9LDfhJINYahWOIlY3SXlZlWKFsAOW+l5oPyPh2vy7d d6Y+usMtB47GLTZoQa8P3DtVyb3O8IxpPERQ+rhOyGHKi0b+m4/kZQSvi2er4ZgVM3Sq FbpAvqW+X+trv/xMDeyBGDIjQZbyENYOj8e4k= Received: by 10.210.76.4 with SMTP id y4mr1263823eba.61.1245626449842; Sun, 21 Jun 2009 16:20:49 -0700 (PDT) Received: from omega.lan (bl9-155-202.dsl.telepac.pt [85.242.155.202]) by mx.google.com with ESMTPS id 7sm858355eyb.45.2009.06.21.16.20.49 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 21 Jun 2009 16:20:49 -0700 (PDT) Sender: Rui Paulo Message-Id: <24E87026-4696-4E59-8CF2-F038FE95A3E7@freebsd.org> From: Rui Paulo To: Michael In-Reply-To: <4A3E9A41.3070101@bindone.de> Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v935.3) Date: Mon, 22 Jun 2009 00:20:48 +0100 References: <4A3E1784.2050406@bindone.de> <5AFA3C27-D3DB-48DA-9AF3-9E14D11EEC61@freebsd.org> <4A3E6563.7040400@bindone.de> <8F2C596E-1B49-4E15-ACC0-84C1A14BD245@freebsd.org> <4A3E6796.4010501@bindone.de> <4A3E7F85.8040309@bindone.de> <95927F48-2E42-4BD6-AB33-CC21D857AD84@freebsd.org> <4A3E9A41.3070101@bindone.de> X-Mailer: Apple Mail (2.935.3) Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Jun 2009 23:20:51 -0000 I'll have my tree ready and I'll commit this next Tuesday. Regards, -- Rui Paulo From owner-freebsd-acpi@FreeBSD.ORG Mon Jun 22 11:06:49 2009 Return-Path: Delivered-To: freebsd-acpi@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0A6C21065679 for ; Mon, 22 Jun 2009 11:06:49 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id EB3E18FC27 for ; Mon, 22 Jun 2009 11:06:48 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n5MB6mko017905 for ; Mon, 22 Jun 2009 11:06:48 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n5MB6m3L017901 for freebsd-acpi@FreeBSD.org; Mon, 22 Jun 2009 11:06:48 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 22 Jun 2009 11:06:48 GMT Message-Id: <200906221106.n5MB6m3L017901@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-acpi@FreeBSD.org Cc: Subject: Current problem reports assigned to freebsd-acpi@FreeBSD.org X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jun 2009 11:06:49 -0000 Note: to view an individual PR, use: http://www.freebsd.org/cgi/query-pr.cgi?pr=(number). The following is a listing of current problems submitted by FreeBSD users. These represent problem reports covering all versions including experimental development code and obsolete releases. S Tracker Resp. Description -------------------------------------------------------------------------------- o bin/135349 acpi [patch] teach acpidump(8) to disassemble arbitrary mem o kern/135070 acpi [acpi] [patch] BIOS resource allocation and FreeBSD AC o kern/132602 acpi [acpi] ACPI Problem with Intel SS4200: System does not o kern/130683 acpi [ACPI] shutdown hangs after syncing disks - ACPI race? o i386/129953 acpi [acpi] ACPI timeout (CDROM) with Shuttle X27D o kern/129618 acpi [acpi] Problem with ACPI on HP Pavilion DV2899 laptop o kern/129563 acpi [acpi] sleep broken on IBM/Lenovo T61 in amd64 mode f kern/128639 acpi [patch] [acpi_asus] acpi for ASUS A6F,A3E,A3F,A3N not f kern/128634 acpi [patch] fix acpi_asus(4) in asus a6f laptop o kern/127581 acpi [patch] [acpi_sony] Add support for more Sony features o kern/124744 acpi [acpi] [patch] incorrect _BST result validation for To o kern/124412 acpi [acpi] power off error on Toshiba M40 laptop o kern/123039 acpi [acpi] ACPI AML_BUFFER_LIMIT errors during boot o kern/121504 acpi [patch] Correctly set hw.acpi.osname on certain machin f kern/121454 acpi [pst] Promise SuperTrak SX6000 does not load during bo o amd64/121439 acpi [boot] Installation of FreeBSD 7.0 fails: ACPI problem o kern/121102 acpi [acpi_fujitsu] [patch] update acpi_fujitsu for the P80 o kern/120515 acpi [acpi] [patch] acpi_alloc_wakeup_handler: can't alloc o kern/119356 acpi [acpi]: i386 ACPI wakeup not work due resource exhaust o kern/119200 acpi [acpi] Lid close switch suspends CPU for 1 second on H o kern/118973 acpi [acpi]: Kernel panic with acpi boot o kern/117605 acpi [acpi] [request] add debug.cpufreq.highest o kern/116939 acpi [acpi] PCI-to-PCI misconfigured for bus three and can o i386/114562 acpi [acpi] cardbus is dead after s3 on Thinkpad T43 with a o kern/114165 acpi [acpi] Dell C810 - ACPI problem s kern/112544 acpi [acpi] [patch] Add High Precision Event Timer Driver f o kern/108954 acpi [acpi] 'sleep(1)' sleeps >1 seconds when speedstep (Cx o kern/108695 acpi [acpi]: Fatal trap 9: general protection fault when in o kern/108488 acpi [acpi] ACPI-1304: *** Error: Method execution failed o kern/108017 acpi [acpi]: Acer Aspire 5600 o kern/106924 acpi [acpi] ACPI resume returns g_vfs_done() errors and ker o kern/105537 acpi [acpi] problems in acpi on HP Compaq nc6320 o kern/104625 acpi ACPI on ASUS A8N-32 SLI/ASUS P4P800 does not show ther o kern/102252 acpi acpi thermal does not work on Abit AW8D (intel 975) o kern/97383 acpi Volume buttons on IBM Thinkpad crash system with ACPI s i386/91748 acpi acpi problem on Acer TravelMare 4652LMi (nvidia panic, s kern/91038 acpi [panic] [ata] [acpi] 6.0-RELEASE on Fujitsu Siemens Am s kern/90243 acpi Laptop fan doesn't turn off (ACPI enabled) (Packard Be f kern/89411 acpi [acpi] acpiconf bug o i386/83018 acpi [install] Installer will not boot on Asus P4S8X BIOS 1 o kern/81000 acpi [apic] Via 8235 sound card worked great with FreeBSD 5 o i386/79081 acpi ACPI suspend/resume not working on HP nx6110 o kern/76950 acpi ACPI wrongly blacklisted on Micron ClientPro 766Xi sys s kern/73823 acpi [request] acpi / power-on by timer support o i386/72566 acpi ACPI, FreeBSD disables fan on Compaq Armada 1750 o i386/69750 acpi Boot without ACPI failed on ASUS L5 o kern/56024 acpi ACPI suspend drains battery while in S3 o i386/55661 acpi ACPI suspend/resume problem on ARMADA M700 o i386/54756 acpi ACPI suspend/resume problem on CF-W2 laptop 49 problems total. From owner-freebsd-acpi@FreeBSD.ORG Mon Jun 22 16:47:00 2009 Return-Path: Delivered-To: freebsd-acpi@FreeBSD.org Received: from [127.0.0.1] (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by hub.freebsd.org (Postfix) with ESMTP id 970E2106564A; Mon, 22 Jun 2009 16:47:00 +0000 (UTC) (envelope-from jkim@FreeBSD.org) From: Jung-uk Kim To: freebsd-acpi@FreeBSD.org Date: Mon, 22 Jun 2009 12:46:44 -0400 User-Agent: KMail/1.6.2 References: <4A3DEEFC.4010204@gmx.de> In-Reply-To: <4A3DEEFC.4010204@gmx.de> MIME-Version: 1.0 Content-Disposition: inline Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <200906221246.47751.jkim@FreeBSD.org> Cc: Subject: Re: Resume problem (Motherboard: MSI 790GX-G65) X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jun 2009 16:47:00 -0000 On Sunday 21 June 2009 04:27 am, hexanism@gmx.de wrote: > Hello, > > I am using suspend/resume (S3) a lot in Linux. Unfortunately I > could not get it to work with FreeBSD. I wanted to solve the > Problem by trying the hints in the FreeBSD manual. I could not get > it to work. Maybe someone can point me in the right direction, I do > not have any experience with ACPI/dsdt debugging. > > The motherboard I am using is a MSI 790GX-G65 featuring the AMD 790 > Chipset. This model is quite a new AM3 board. It has an onboard > 3D-accelerated AMD graphics card. The Bios is up to date (Revision > 1.3). I am using FreeBSD 7.2-RC2 with the generic kernel (I also > did all the testing with another hardrive using FreeBSD > 7.2-RELEASE). -- >8 --- SNIP!!! --- >8 --- Unfortunately i386/SMP does not support S3. Jung-uk Kim From owner-freebsd-acpi@FreeBSD.ORG Mon Jun 22 20:00:35 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 583FD1065677 for ; Mon, 22 Jun 2009 20:00:35 +0000 (UTC) (envelope-from hexanism@gmx.de) Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by mx1.freebsd.org (Postfix) with SMTP id 935518FC12 for ; Mon, 22 Jun 2009 20:00:32 +0000 (UTC) (envelope-from hexanism@gmx.de) Received: (qmail invoked by alias); 22 Jun 2009 19:59:32 -0000 Received: from koln-4db410de.pool.einsundeins.de (EHLO phenom.home.network) [77.180.16.222] by mail.gmx.net (mp065) with SMTP; 22 Jun 2009 21:59:32 +0200 X-Authenticated: #12668306 X-Provags-ID: V01U2FsdGVkX1+zupgx09Wzun/FQGp+qDMhPdIbdiOatMX0ebbqxZ JKmqGxbxkOW465 Message-ID: <4A3FE2A0.8060409@gmx.de> Date: Mon, 22 Jun 2009 21:59:28 +0200 From: "hexanism@gmx.de" User-Agent: Thunderbird 2.0.0.21 (X11/20090605) MIME-Version: 1.0 To: freebsd-acpi@freebsd.org References: <4A3DEEFC.4010204@gmx.de> <4911F71203A09E4D9981D27F9D8308582E8438B7@orsmsx503.amr.corp.intel.com> In-Reply-To: <4911F71203A09E4D9981D27F9D8308582E8438B7@orsmsx503.amr.corp.intel.com> Content-Type: multipart/mixed; boundary="------------070401030001050607010509" X-Y-GMX-Trusted: 0 X-FuHaFi: 0.51,0.57 Subject: Re: Resume problem (Motherboard: MSI 790GX-G65) X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jun 2009 20:00:35 -0000 This is a multi-part message in MIME format. --------------070401030001050607010509 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hello, thank you very much Robert for patching the dsdt. I compiled it by myself and got five other errors (Use of reserved word: _T_0, _T_1). I don't know if these are severe. I loaded your patched dsdt instead of the original one and I got the same behavior (the pc does not resume). As Jung-uk pointed out, S3 is not supported for i386/SMP which I did not know. I would love to run FreeBSD/amd64. I had it installed some weeks ago (7.0, I think)but unfortunately S3 was missing when executing 'sysctl hw.acpi.supported_sleep_state'. So I decided to check FreeBSD/i386. If I got it right then it does not make sense trying to get S3 working on FreeBSD/i386 because of missing SMP support. On the other hand there is the problem of the missing S3 value in 'hw.acpi.supported_sleep_state'. Is S3 generally not supported in FreeBSD/amd64, or is it because of the buggy BIOS of this specific motherboard? Is there a chance to get S3 working for my machine? Thank you very much for your help. regards, Chris Moore, Robert wrote: > Attached are the updated DSDT and output from iASL, and compiled AML file. > > > > > >> -----Original Message----- >> From: owner-freebsd-acpi@freebsd.org [mailto:owner-freebsd- >> acpi@freebsd.org] On Behalf Of hexanism@gmx.de >> Sent: Sunday, June 21, 2009 1:28 AM >> To: freebsd-acpi@freebsd.org >> Subject: Resume problem (Motherboard: MSI 790GX-G65) >> >> Hello, >> >> I am using suspend/resume (S3) a lot in Linux. Unfortunately I could not >> get it to work with FreeBSD. I wanted to solve the Problem by trying the >> hints in the FreeBSD manual. I could not get it to work. Maybe someone >> can point me in the right direction, I do not have any experience with >> ACPI/dsdt debugging. >> >> The motherboard I am using is a MSI 790GX-G65 featuring the AMD 790 >> Chipset. This model is quite a new AM3 board. It has an onboard >> 3D-accelerated AMD graphics card. The Bios is up to date (Revision 1.3). >> I am using FreeBSD 7.2-RC2 with the generic kernel (I also did all >> the testing with another hardrive using FreeBSD 7.2-RELEASE). >> >> Suspend and resume work with Linux (Ubuntu 9.04) and Windows XP 64 >> flawlessly. >> >> S1 freezes the screen about two seconds after calling "acpiconf -s 1". >> Then I have to press the reset button. S3/suspend seems to work. The >> Fans and drives turn off and the power led acts exactly the same way as >> it acts under Linux and Windows. Under Linux/Windows I can resume by >> Keyboard. Under FreeBSD that does not work, I have to press the power >> button to get the computer to react. Unfortunately the screen stays >> black (drives and fans do get turned on). I have to press the reset button. >> >> I inspected the dsdt of my motherboard: >> >> http://innoits.de/chris-msi790gx65.asl >> >> There are a lot of errors when recompiling with iasl (about 180 Errors, >> most of them "Object does not exist"). I downloaded the ACPI >> specifications (3.0a, 3.0b and 4.0) but could not fix the Errors (I >> started with the first one ;)) due to my lack of knowledge concerning ACPI. >> >> What can I do now? Most of the errors are of the same type. I hope that >> ther is a simple solution that I just can't solve by myself. Is there a >> good beginner friendly dsdt tutorial around? Is it possible that the >> dsdt of my motherboard uses a newer ACPI revision (4.0) and thus is >> incompatible with the current version of iasl? >> >> Thank you very much for reading this... >> >> Chris >> >> > > --------------070401030001050607010509 Content-Type: text/plain; name="errors.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="errors.txt" Intel ACPI Component Architecture ASL Optimizing Compiler version 20070320 [Apr 23 2009] Copyright (C) 2000 - 2007 Intel Corporation Supports ACPI Specification Revision 3.0a acpi/fix_from_robert/dsdt.dsl 518: Name (_T_0, Zero) Error 4081 - Use of reserved word ^ (_T_0) acpi/fix_from_robert/dsdt.dsl 3463: Acquire (ECMU, 0x5000) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 3483: Acquire (ECMU, 0x1388) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 3484: Acquire (MLMU, 0x1388) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 3499: Release (MLMU) Warning 1098 - Statement is unreachable ^ acpi/fix_from_robert/dsdt.dsl 3505: Acquire (ECMU, 0x1388) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 3506: Acquire (MLMU, 0x1388) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 3672: Acquire (ECMU, 0x1388) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 3742: Acquire (ECMU, 0x1388) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 6167: Acquire (MUTE, 0x03E8) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 6181: Acquire (MUTE, 0x03E8) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 6196: Acquire (MUTE, 0x03E8) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 6211: Acquire (MUTE, 0x0FFF) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 6225: Acquire (MUTE, 0x03E8) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 6240: Acquire (MUTE, 0x03E8) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 6255: Acquire (MUTE, 0x03E8) Warning 1103 - Possible operator timeout is ignored ^ acpi/fix_from_robert/dsdt.dsl 9069: Add (Local1, 0x80) Warning 1104 - Result is not used, operator has no effect ^ acpi/fix_from_robert/dsdt.dsl 9519: Method (WMAA, 3, NotSerialized) Warning 1086 - Not all control paths return a value ^ (WMAA) acpi/fix_from_robert/dsdt.dsl 10615: Name (_T_0, Zero) Error 4081 - Use of reserved word ^ (_T_0) acpi/fix_from_robert/dsdt.dsl 10750: Name (_T_1, Zero) Error 4081 - Use of reserved word ^ (_T_1) acpi/fix_from_robert/dsdt.dsl 10821: Name (_T_0, Zero) Error 4081 - Use of reserved word ^ (_T_0) acpi/fix_from_robert/dsdt.dsl 10956: Name (_T_1, Zero) Error 4081 - Use of reserved word ^ (_T_1) ASL Input: acpi/fix_from_robert/dsdt.dsl - 11631 lines, 381904 bytes, 3743 keywords Compilation complete. 5 Errors, 17 Warnings, 0 Remarks, 98 Optimizations --------------070401030001050607010509-- From owner-freebsd-acpi@FreeBSD.ORG Mon Jun 22 20:21:07 2009 Return-Path: Delivered-To: freebsd-acpi@FreeBSD.org Received: from [127.0.0.1] (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by hub.freebsd.org (Postfix) with ESMTP id BF68B10656E3; Mon, 22 Jun 2009 20:21:07 +0000 (UTC) (envelope-from jkim@FreeBSD.org) From: Jung-uk Kim To: freebsd-acpi@FreeBSD.org Date: Mon, 22 Jun 2009 16:20:52 -0400 User-Agent: KMail/1.6.2 References: <4A3DEEFC.4010204@gmx.de> <4911F71203A09E4D9981D27F9D8308582E8438B7@orsmsx503.amr.corp.intel.com> <4A3FE2A0.8060409@gmx.de> In-Reply-To: <4A3FE2A0.8060409@gmx.de> MIME-Version: 1.0 Content-Disposition: inline Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <200906221620.55619.jkim@FreeBSD.org> Cc: Subject: Re: Resume problem (Motherboard: MSI 790GX-G65) X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jun 2009 20:21:09 -0000 On Monday 22 June 2009 03:59 pm, hexanism@gmx.de wrote: > If I got it right then it does not make sense trying to get S3 > working on FreeBSD/i386 because of missing SMP support. On the > other hand there is the problem of the missing S3 value in > 'hw.acpi.supported_sleep_state'. Is S3 generally not supported in > FreeBSD/amd64, or is it because of the buggy BIOS of this specific > motherboard? Is there a chance to get S3 working for my machine? FreeBSD -CURRENT support S3 on amd64 for both UP and SMP. 7.x does not have necessary code. Jung-uk Kim From owner-freebsd-acpi@FreeBSD.ORG Mon Jun 22 20:21:40 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 59AF410656C3 for ; Mon, 22 Jun 2009 20:21:40 +0000 (UTC) (envelope-from peter.piggybox@virgin.net) Received: from smtprelay-virgin.hostedemail.com (smtprelay-virgin0163.hostedemail.com [64.99.136.163]) by mx1.freebsd.org (Postfix) with ESMTP id 109478FC08 for ; Mon, 22 Jun 2009 20:21:39 +0000 (UTC) (envelope-from peter.piggybox@virgin.net) Received: from filter.hostedemail.com (ff-bigip1 [10.5.19.254]) by smtprelay06.hostedemail.com (Postfix) with SMTP id B9799195FE6; Mon, 22 Jun 2009 20:21:38 +0000 (UTC) X-Spam-Summary: 2, 0, 0, 2e7b1a92d472667d, d41d8cd98f00b204, peter.piggybox@virgin.net, naylor.b.david@gmail.com:peter.piggybox@virgin.net:ivakras1@gmail.com:freebsd-acpi@freebsd.org, RULES_HIT:355:379:599:601:945:966:973:988:989:1260:1261:1277:1312:1313:1314:1345:1359:1437:1516:1518:1519:1534:1542:1593:1594:1595:1596:1605:1711:1730:1747:1766:1792:1981:2194:2196:2198:2199:2200:2201:2377:2393:2551:2553:2559:2562:2693:2894:3027:3622:3865:3866:3867:3868:3869:3870:3871:3872:3873:3874:3961:4184:4362:4385:4699:5007:6119:6261:7903:7904:7974:10004, 0, RBL:none, CacheIP:none, Bayesian:0.5, 0.5, 0.5, Netcheck:none, DomainCache:0, MSF:not bulk, SPF:fn, MSBL:none, DNSBL:none, Custom_rules:0:0:0 X-Filterd-Recvd-Size: 4165 Received: from ideapad.piggybox (client-81-105-211-85.mcr-bng-011.adsl.virginmedia.net [81.105.211.85]) by omf11.hostedemail.com (Postfix) with ESMTP; Mon, 22 Jun 2009 20:21:33 +0000 (UTC) Received: from ideapad.piggybox (localhost [127.0.0.1]) by ideapad.piggybox (8.14.3/8.14.3) with ESMTP id n5MJKYd9001107; Mon, 22 Jun 2009 20:20:35 +0100 (BST) (envelope-from peter@ideapad.piggybox) Received: (from peter@localhost) by ideapad.piggybox (8.14.3/8.14.3/Submit) id n5MJKY7f001106; Mon, 22 Jun 2009 20:20:34 +0100 (BST) (envelope-from peter) Date: Mon, 22 Jun 2009 20:20:34 +0100 From: Peter Harrison To: David Naylor Message-ID: <20090622192034.GA1059@ideapad.piggybox> References: <200906181407.11607.naylor.b.david@gmail.com> <200906182100.15817.naylor.b.david@gmail.com> <20090620130403.GA1051@ideapad.piggybox> <200906211400.19033.naylor.b.david@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200906211400.19033.naylor.b.david@gmail.com> User-Agent: Mutt/1.4.2.3i Cc: freebsd-acpi@freebsd.org, Peter Harrison Subject: Re: [PATCH] Lenovo S10(e) ACPI X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jun 2009 20:21:40 -0000 Sunday, 21 June 2009 at 14:00:14 +0200, David Naylor said: > On Saturday 20 June 2009 15:04:03 Peter Harrison wrote: > > Thursday, 18 June 2009 at 21:00:11 +0200, David Naylor said: > > > On Thursday 18 June 2009 19:40:28 Peter Harrison wrote: > > > > Thursday, 18 June 2009 at 14:07:07 +0200, David Naylor said: > > > > > Hi, > > > > > > > > > > ((Short version: apply patch and add 'debug.acpi.ec.gpe=1' > > > > > and 'debug.acpi.ec.timeout=100' to loader.conf and EC (battery, > > > > > thermal) ?should? work)) > > > > > > > > > > P.S. If this doesn't work please include details (and dmesg output) > > > > > and I'll try to help. > > > > David, > > > > The patch applied cleanly, and I've rebuilt and installed. System seems to > > work fine and I'm getting battery time reported properly. It still won't > > poweroff on shutdown though... > > > > uname -a: > > FreeBSD ideapad.piggybox 7.2-RELEASE-p1 FreeBSD 7.2-RELEASE-p1 #0: Sat Jun > > 20 11:03:21 BST 2009 > > peter@ideapad.piggybox:/usr/obj/usr/src/sys/GENERIC i386 > > > > dmesg: > I can't see anything that shouts out as being wrong, EC attaches correctly and > no timeout errors. > > Please see attached for a new patch, it fixes a potential (but unlikely) race > condition that could freeze the EC. It also 'fixes' the timeout problem > (well, the workaround seems more stable). > > This adds another tunable/sysctl called ``debug.acpi.ec.delay''. It defaults > to 0 (no change) but when set to a value it adds a delay (in microseconds) > after each successful request. This delay (at about ~200) appears to fix the > problem. I'll still recommend having debug.acpi.ec.gpe and > debug.acpi.ec.timeout set (just in case). So you should have in loader.conf: > > debug.acpi.ec.delay="200" # (us) > debug.acpi.ec.gpe="1" # Optional but recommended > debug.acpi.ec.timeout="100" # (ms) Optional but recommended > > If you are getting some `wait timeout' messages you can try increasing > debug.acpi.ec.delay. > > I'm not sure what is stopping your computer from shutting down (have you tried > `halt -p`?). The only difference that I can spot if that I'm using -current > (with the new acpi code). The patch may work, otherwise you could > give -current a try (it is probably easy enough to backport the ACPI > import...). > > Regards, > > David Hi David, Thanks for coming back to me - I haven't had a chance to test the new patch yet, but will get on to it as soon as I can. Is just a kernel rebuild enough after patching? Last time a did kernel + world to pick up the last security advisory too and it was a bit painful (even slower than my old Celeron M based Dell laptop). I'm still reeling from a packaged based upgrade of Firefox (still took a while, even using packages). Thanks again for your help. Peter. From owner-freebsd-acpi@FreeBSD.ORG Mon Jun 22 20:44:24 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 330C91065670 for ; Mon, 22 Jun 2009 20:44:24 +0000 (UTC) (envelope-from robert.moore@intel.com) Received: from mga03.intel.com (mga03.intel.com [143.182.124.21]) by mx1.freebsd.org (Postfix) with ESMTP id 099498FC14 for ; Mon, 22 Jun 2009 20:44:23 +0000 (UTC) (envelope-from robert.moore@intel.com) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 22 Jun 2009 13:44:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.42,271,1243839600"; d="scan'208";a="157273291" Received: from orsmsx603.amr.corp.intel.com ([10.22.226.49]) by azsmga001.ch.intel.com with ESMTP; 22 Jun 2009 13:44:23 -0700 Received: from orsmsx503.amr.corp.intel.com ([10.22.226.47]) by orsmsx603.amr.corp.intel.com ([10.22.226.49]) with mapi; Mon, 22 Jun 2009 13:44:22 -0700 From: "Moore, Robert" To: "hexanism@gmx.de" , "freebsd-acpi@freebsd.org" Date: Mon, 22 Jun 2009 13:44:21 -0700 Thread-Topic: Resume problem (Motherboard: MSI 790GX-G65) Thread-Index: AcnzdELERgkdmtcES+Kmkz8afF88vAABaWXg Message-ID: <4911F71203A09E4D9981D27F9D8308582E843FA2@orsmsx503.amr.corp.intel.com> References: <4A3DEEFC.4010204@gmx.de> <4911F71203A09E4D9981D27F9D8308582E8438B7@orsmsx503.amr.corp.intel.com> <4A3FE2A0.8060409@gmx.de> In-Reply-To: <4A3FE2A0.8060409@gmx.de> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Cc: Subject: RE: Resume problem (Motherboard: MSI 790GX-G65) X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Jun 2009 20:44:24 -0000 >thank you very much Robert for patching the dsdt. I compiled it by >myself and got five other errors (Use of reserved word: _T_0, _T_1). I >don't know if these are severe. I loaded your patched dsdt instead of This error has been reduced to a remark in newer versions of the compiler. = They are compiler temporary variables that are introduced during the compil= ation of the original source by the bios vendor. They appear when the origi= nal (compiled) code is disassembled. >-----Original Message----- >From: owner-freebsd-acpi@freebsd.org [mailto:owner-freebsd- >acpi@freebsd.org] On Behalf Of hexanism@gmx.de >Sent: Monday, June 22, 2009 12:59 PM >To: freebsd-acpi@freebsd.org >Subject: Re: Resume problem (Motherboard: MSI 790GX-G65) > >Hello, > >thank you very much Robert for patching the dsdt. I compiled it by >myself and got five other errors (Use of reserved word: _T_0, _T_1). I >don't know if these are severe. I loaded your patched dsdt instead of >the original one and I got the same behavior (the pc does not resume). >As Jung-uk pointed out, S3 is not supported for i386/SMP which I did not >know. I would love to run FreeBSD/amd64. I had it installed some weeks >ago (7.0, I think)but unfortunately S3 was missing when executing >'sysctl hw.acpi.supported_sleep_state'. So I decided to check FreeBSD/i386= . > >If I got it right then it does not make sense trying to get S3 working >on FreeBSD/i386 because of missing SMP support. On the other hand there >is the problem of the missing S3 value in >'hw.acpi.supported_sleep_state'. Is S3 generally not supported in >FreeBSD/amd64, or is it because of the buggy BIOS of this specific >motherboard? Is there a chance to get S3 working for my machine? > >Thank you very much for your help. > >regards, > >Chris > > > > >Moore, Robert wrote: >> Attached are the updated DSDT and output from iASL, and compiled AML >file. >> >> >> >> >> >>> -----Original Message----- >>> From: owner-freebsd-acpi@freebsd.org [mailto:owner-freebsd- >>> acpi@freebsd.org] On Behalf Of hexanism@gmx.de >>> Sent: Sunday, June 21, 2009 1:28 AM >>> To: freebsd-acpi@freebsd.org >>> Subject: Resume problem (Motherboard: MSI 790GX-G65) >>> >>> Hello, >>> >>> I am using suspend/resume (S3) a lot in Linux. Unfortunately I could no= t >>> get it to work with FreeBSD. I wanted to solve the Problem by trying th= e >>> hints in the FreeBSD manual. I could not get it to work. Maybe someone >>> can point me in the right direction, I do not have any experience with >>> ACPI/dsdt debugging. >>> >>> The motherboard I am using is a MSI 790GX-G65 featuring the AMD 790 >>> Chipset. This model is quite a new AM3 board. It has an onboard >>> 3D-accelerated AMD graphics card. The Bios is up to date (Revision 1.3)= . >>> I am using FreeBSD 7.2-RC2 with the generic kernel (I also did all >>> the testing with another hardrive using FreeBSD 7.2-RELEASE). >>> >>> Suspend and resume work with Linux (Ubuntu 9.04) and Windows XP 64 >>> flawlessly. >>> >>> S1 freezes the screen about two seconds after calling "acpiconf -s 1". >>> Then I have to press the reset button. S3/suspend seems to work. The >>> Fans and drives turn off and the power led acts exactly the same way as >>> it acts under Linux and Windows. Under Linux/Windows I can resume by >>> Keyboard. Under FreeBSD that does not work, I have to press the power >>> button to get the computer to react. Unfortunately the screen stays >>> black (drives and fans do get turned on). I have to press the reset >button. >>> >>> I inspected the dsdt of my motherboard: >>> >>> http://innoits.de/chris-msi790gx65.asl >>> >>> There are a lot of errors when recompiling with iasl (about 180 Errors, >>> most of them "Object does not exist"). I downloaded the ACPI >>> specifications (3.0a, 3.0b and 4.0) but could not fix the Errors (I >>> started with the first one ;)) due to my lack of knowledge concerning >ACPI. >>> >>> What can I do now? Most of the errors are of the same type. I hope that >>> ther is a simple solution that I just can't solve by myself. Is there a >>> good beginner friendly dsdt tutorial around? Is it possible that the >>> dsdt of my motherboard uses a newer ACPI revision (4.0) and thus is >>> incompatible with the current version of iasl? >>> >>> Thank you very much for reading this... >>> >>> Chris >>> >>> >> >> From owner-freebsd-acpi@FreeBSD.ORG Tue Jun 23 12:47:12 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7C0A5106564A; Tue, 23 Jun 2009 12:47:12 +0000 (UTC) (envelope-from rea-fbsd@codelabs.ru) Received: from 0.mx.codelabs.ru (0.mx.codelabs.ru [144.206.177.45]) by mx1.freebsd.org (Postfix) with ESMTP id 1E7FD8FC18; Tue, 23 Jun 2009 12:47:11 +0000 (UTC) (envelope-from rea-fbsd@codelabs.ru) DomainKey-Signature: a=rsa-sha1; q=dns; c=simple; s=one; d=codelabs.ru; h=Received:Date:From:To:Cc:Subject:Message-ID:Reply-To:References:MIME-Version:Content-Type:Content-Disposition:In-Reply-To:Sender; b=hHi/eiwTUgYLyoKOeTPO8rmJkKaqdJ9WO1tBAI4e4HZH/rJgJ1+9X/RL6BcSlGuLbSKz+sKlh4PqlptQLM0WvHZye03R9HQ0YempdmWnEqC2U7qdIHKcFQ6VIlo8CDnnk7RR9CB/X50iUvWO2lYmgASEfzw8cZcaKqMDV2qSXkE=; Received: from void.codelabs.ru (void.codelabs.ru [144.206.177.25]) by 0.mx.codelabs.ru with esmtpsa (TLSv1:AES256-SHA:256) id 1MJ5P3-000KOl-Em; Tue, 23 Jun 2009 16:47:09 +0400 Date: Tue, 23 Jun 2009 16:47:06 +0400 From: "rea-fbsd@codelabs.ru" To: "Moore, Robert" Message-ID: <0wbH8rW09IccaqMqHobLApUP2FQ@hJhSod24P8TdBWT2Rda0vGnf2ew> References: <4A32CA38.4020806@root.org> <4911F71203A09E4D9981D27F9D8308582E76D375@orsmsx503.amr.corp.intel.com> <4911F71203A09E4D9981D27F9D8308582E76D4A3@orsmsx503.amr.corp.intel.com> <4A3B6761.4030503@icyb.net.ua> <4A3B6DB7.9050408@icyb.net.ua> <4911F71203A09E4D9981D27F9D8308582E7E4C93@orsmsx503.amr.corp.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4911F71203A09E4D9981D27F9D8308582E7E4C93@orsmsx503.amr.corp.intel.com> Sender: rea-fbsd@codelabs.ru Cc: "freebsd-acpi@freebsd.org" , Andriy Gapon , Jung-uk Kim Subject: Re: [PATCH] acpidump: teach to disassemble arbitrary memory locations as AML code X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: rea-fbsd@codelabs.ru List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2009 12:47:12 -0000 Robert, good day. Fri, Jun 19, 2009 at 09:04:50AM -0700, Moore, Robert wrote: > I actually already have an os-independent, acpica-compatible version > of acpidump.c. I can send it out if people want to work on it. Yes, please -- this will be great: I had already started to play with pmtools' acpidump, but spent not too much time, so the newer utility version will be a better playground. > The main thing that still needs to be done is to define how the > os-independent part interacts with the os-dependent part. I thinks that we will be able to settle this ;)) Thanks! -- Eygene _ ___ _.--. # \`.|\..----...-'` `-._.-'_.-'` # Remember that it is hard / ' ` , __.--' # to read the on-line manual )/' _/ \ `-_, / # while single-stepping the kernel. `-'" `"\_ ,_.-;_.-\_ ', fsc/as # _.-'_./ {_.' ; / # -- FreeBSD Developers handbook {_.-``-' {_/ # From owner-freebsd-acpi@FreeBSD.ORG Tue Jun 23 13:07:30 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CC4AF106566C for ; Tue, 23 Jun 2009 13:07:30 +0000 (UTC) (envelope-from niktychina@gmail.com) Received: from fg-out-1718.google.com (fg-out-1718.google.com [72.14.220.155]) by mx1.freebsd.org (Postfix) with ESMTP id 5380A8FC22 for ; Tue, 23 Jun 2009 13:07:29 +0000 (UTC) (envelope-from niktychina@gmail.com) Received: by fg-out-1718.google.com with SMTP id l26so146530fgb.12 for ; Tue, 23 Jun 2009 06:07:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type; bh=CollW9FfYuC522Yy09pwBeaBwch4SY2oM/PRr5d0YEI=; b=A9ruZPPPXAEVC2FhJXP+0Mbbpqw0JJjlD6gg6dWnCCUZrgtgstXyze5foKpy0Le7AQ B7pToMcHKsKk19bBgm6YauXz8xTdGlAG7PQTry/mmXuOEMxxnvNy+gLpkrDHdw7l0oJB Tj5703X0y1Dsjju3v9eSOadmI8EKlWeY9d7/k= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=U/m4kI1IVucpQKCTxi/3XVOCQ+aMzvtN70aN1lIzpTBCSyChtqGSMKO7QzOHLe13qY rIAbNK6O4MJv7qsB3krwxUfXliixNSwhmcp6BkDIxPn8rJ08oGokVLayHcKwbbQsezRY TIpmJ42rc9CpxdkxqKhOrubzCdgyQVVG5is+4= MIME-Version: 1.0 Received: by 10.86.91.3 with SMTP id o3mr149945fgb.29.1245762449278; Tue, 23 Jun 2009 06:07:29 -0700 (PDT) In-Reply-To: <24E87026-4696-4E59-8CF2-F038FE95A3E7@freebsd.org> References: <4A3E1784.2050406@bindone.de> <4A3E6563.7040400@bindone.de> <8F2C596E-1B49-4E15-ACC0-84C1A14BD245@freebsd.org> <4A3E6796.4010501@bindone.de> <4A3E7F85.8040309@bindone.de> <95927F48-2E42-4BD6-AB33-CC21D857AD84@freebsd.org> <4A3E9A41.3070101@bindone.de> <24E87026-4696-4E59-8CF2-F038FE95A3E7@freebsd.org> Date: Tue, 23 Jun 2009 17:07:29 +0400 Message-ID: From: Nikolay Tychina To: Rui Paulo , freebsd-acpi@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2009 13:07:31 -0000 Hi, do these modules work for ACER laptops? Thanks 2009/6/22 Rui Paulo > I'll have my tree ready and I'll commit this next Tuesday. > > Regards, > > -- > Rui Paulo > > _______________________________________________ > freebsd-acpi@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-acpi > To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org" > From owner-freebsd-acpi@FreeBSD.ORG Tue Jun 23 14:54:08 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C987F1065676 for ; Tue, 23 Jun 2009 14:54:08 +0000 (UTC) (envelope-from naylor.b.david@gmail.com) Received: from mail-ew0-f212.google.com (mail-ew0-f212.google.com [209.85.219.212]) by mx1.freebsd.org (Postfix) with ESMTP id 4B57D8FC1A for ; Tue, 23 Jun 2009 14:54:08 +0000 (UTC) (envelope-from naylor.b.david@gmail.com) Received: by ewy8 with SMTP id 8so174861ewy.43 for ; Tue, 23 Jun 2009 07:54:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:organization:to:subject :date:user-agent:cc:references:in-reply-to:mime-version:content-type :content-transfer-encoding:message-id; bh=VYPj+J9srEOYfIqkpDVLYJkdYWhPQR2J01P6WpauTT0=; b=UIVIw/6MpBrMd/5FEf1BTT5MXwSN5/sqnsjtEbwGCrR/3ifBwZ1R1+JHF8KWgmritA oh+lCqcst2dtqI11zod0cN2nYfme/pGSBC9/P8jj1hOr6NOcKVJ9NKLL2csfOG+xP4Wg BbZLR0By8BDREK1Jnqz5ma90BK45lXwIPvNKE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:organization:to:subject:date:user-agent:cc:references :in-reply-to:mime-version:content-type:content-transfer-encoding :message-id; b=tSY0BpL10W/IUjyVaDDxBNd8McYHOZa1VNLKzHJ2P3QTvp9/d5FkbqhxX38COMvdpp BqR+6OdM6DZuMFEJAirpU1U3GQRWGjh1D2uMNV4339dbuh/nPJnj/HafDAfaQG5ga0hG ptsrWEHeF+SyaWB9evd2uvNvAJ0eHlKV6DWrY= Received: by 10.210.58.13 with SMTP id g13mr187696eba.48.1245768847275; Tue, 23 Jun 2009 07:54:07 -0700 (PDT) Received: from dragonmini.dg ([196.34.241.123]) by mx.google.com with ESMTPS id 5sm5677eyf.57.2009.06.23.07.54.04 (version=SSLv3 cipher=RC4-MD5); Tue, 23 Jun 2009 07:54:06 -0700 (PDT) From: David Naylor Organization: Private To: Peter Harrison Date: Tue, 23 Jun 2009 16:55:19 +0200 User-Agent: KMail/1.9.10 References: <200906181407.11607.naylor.b.david@gmail.com> <200906211400.19033.naylor.b.david@gmail.com> <20090622192034.GA1059@ideapad.piggybox> In-Reply-To: <20090622192034.GA1059@ideapad.piggybox> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart2109565.Y3gttBW5YO"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit Message-Id: <200906231655.23010.naylor.b.david@gmail.com> Cc: freebsd-acpi@freebsd.org Subject: Re: [PATCH] Lenovo S10(e) ACPI X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2009 14:54:09 -0000 --nextPart2109565.Y3gttBW5YO Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Monday 22 June 2009 21:20:34 Peter Harrison wrote: > > David > > Hi David, > > Thanks for coming back to me - I haven't had a chance to test the new pat= ch > yet, but will get on to it as soon as I can. > > Is just a kernel rebuild enough after patching? Last time a did kernel += =20 > world to pick up the last security advisory too and it was a bit painful > (even slower than my old Celeron M based Dell laptop). If you don't have ACPI compiled into the kernel then only that module needs= to=20 be rebuilt, otherwise only the kernel needs to be rebuilt. =20 > I'm still reeling from a packaged based upgrade of Firefox (still took a > while, even using packages). > > Thanks again for your help. I'll be away for the next 3 weeks so can only help you after that. =20 Good luck, David --nextPart2109565.Y3gttBW5YO Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (FreeBSD) iEYEABECAAYFAkpA7NoACgkQUaaFgP9pFrJ+3gCfQSQO7XZHGx/XzJwuiv/nS75z svoAn2vMCy65VwKl6MdYEuh5bCAyfuH1 =dSxO -----END PGP SIGNATURE----- --nextPart2109565.Y3gttBW5YO-- From owner-freebsd-acpi@FreeBSD.ORG Tue Jun 23 16:00:23 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 87BDC1065694 for ; Tue, 23 Jun 2009 16:00:22 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 064588FC21 for ; Tue, 23 Jun 2009 16:00:17 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 43828 invoked by uid 89); 23 Jun 2009 16:00:16 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.175.31) by mail.bindone.de with ESMTPA; 23 Jun 2009 16:00:16 -0000 Message-ID: <4A40FBDA.70705@bindone.de> Date: Tue, 23 Jun 2009 17:59:22 +0200 From: Michael User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: Nikolay Tychina References: <4A3E1784.2050406@bindone.de> <4A3E6563.7040400@bindone.de> <8F2C596E-1B49-4E15-ACC0-84C1A14BD245@freebsd.org> <4A3E6796.4010501@bindone.de> <4A3E7F85.8040309@bindone.de> <95927F48-2E42-4BD6-AB33-CC21D857AD84@freebsd.org> <4A3E9A41.3070101@bindone.de> <24E87026-4696-4E59-8CF2-F038FE95A3E7@freebsd.org> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2009 16:00:24 -0000 Nikolay Tychina wrote: > Hi, do these modules work for ACER laptops? > Thanks > > 2009/6/22 Rui Paulo > >> I'll have my tree ready and I'll commit this next Tuesday. >> >> Regards, >> >> -- >> Rui Paulo >> >> _______________________________________________ >> freebsd-acpi@freebsd.org mailing list >> http://lists.freebsd.org/mailman/listinfo/freebsd-acpi >> To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org" >> > _______________________________________________ > freebsd-acpi@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-acpi > To unsubscribe, send any mail to "freebsd-acpi-unsubscribe@freebsd.org" Nope, but acpi_wmi could be the foundation for implementing this. UNfortunately I have no Acer hardware around, so I cannot do this. From owner-freebsd-acpi@FreeBSD.ORG Wed Jun 24 06:09:13 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 03C311065690 for ; Wed, 24 Jun 2009 06:09:13 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 71BDB8FC1E for ; Wed, 24 Jun 2009 06:09:12 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 89080 invoked by uid 89); 24 Jun 2009 06:09:11 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.167.13) by mail.bindone.de with ESMTPA; 24 Jun 2009 06:09:11 -0000 Message-ID: <4A41C2CF.4020205@bindone.de> Date: Wed, 24 Jun 2009 08:08:15 +0200 From: Michael User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: "Paul B. Mahol" References: <4A3E1784.2050406@bindone.de> <3a142e750906232257y4b1e255en9374c05079f04520@mail.gmail.com> In-Reply-To: <3a142e750906232257y4b1e255en9374c05079f04520@mail.gmail.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jun 2009 06:09:13 -0000 Paul B. Mahol wrote: > On 6/21/09, Michael wrote: >> Hello, >> >> I wrote two new acpi modules last year and finally found the time to fix >> them, add some missing features and write man pages. >> >> This is the first time I'm writing kernel code for FreeBSD, so please >> excuse me if I failed to apply to all style conventions (I tried to >> follow style(9) as closely as possible). >> >> acpi_wmi is an ACPI to WMI mapping driver (this is used by HP and Acer >> notebooks and potentially others), so this could also be used to >> implement additional drivers on (see for more details on WMI and ACPI: >> http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx). >> It provides /dev/wmistat, example output: >> cat /dev/wmistat >> GUID INST EXPE METH STR EVENT OID >> {5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA >> {95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - >> {2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - >> {05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB >> {1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA >> {2D114B49-2DFB-4130-B8FE-4A3C09E75133} 57 NO NO NO NO BC >> {988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 20 NO NO NO NO BD >> {14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE >> {322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF >> {8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG >> {8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH >> {8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI >> >> acpi_hp is a driver that uses acpi_wmi to provide HP specific features. >> These include: >> - Activate/deactivate WLAN >> - Activate/deactivate WWAN >> - Activate/deactivate Bluetooth >> - Auto activate/deactiavte based on hw radio status >> - Devd notifications >> - On air status for different >> - Controls ambient light sensor >> - Get docking status >> - Read BIOS settings through /dev/hpcmi, example output: >> Flash Media Reader Disable >> USB Ports including Express Card slot Enable >> 1394 Port Enable >> Cardbus Slot Disable >> Express Card Slot Disable >> F9, F10 and F12 Delay(Sec) 0 >> USB Device Detection Delay (Sec) 0 >> Multiboot Enable >> Express Boot Popup Delay(Sec) 0 >> CD-ROM Boot Enable >> Floppy Boot Disable >> Internal Network Adapter Boot Disable >> Internal Network Adapter Boot Mode PXE >> Swap Fn/Ctrl Key Disable >> USB Legacy Support Disable >> Parallel Port Mode ECP >> ... >> >> The man pages included in the patch (man acpi_hp / man acpi_wmi) give >> you detailed information about all sysctls and devices. >> >> The patch attached (acpi_wmi_and_acpi_hp.patch) has been tested against >> 7.2-RELEASE and everything compiles cleanly, although my tests have been >> on 8-CURRENT (but the snapshot is older than 7.2), so I expect this to >> work ok on 7.2. The patch might fail against CURRENT though, this is why >> I also attached patches.tgz, which contains individual patches per file. >> I only tested this on i386 and the patch only changes i386 specific >> things (I have no idea if this could possibly work on amd64, especially >> because all the other acpi_support modules seem to be i386 only). Also >> note, that I could only test this on my own machine (HP Compaq 8510p), >> which features WLAN/BT/WLAN, so I don't know if the readings will be >> sane if your machine doesn't feature a WWAN chip. In theory this should >> work for many different HP models. >> >> Installation instructions (replace MYKERNEL with your kernel name): >> >> mkdir /usr/src/sys/modules/acpi/acpi_wmi >> mkdir /usr/src/sys/modules/acpi/acpi_hp >> patch -d /usr/src < acpi_wmi_and_acpi_hp.patch >> cd /usr/src/share/man/man4/man4.i386 >> make all && make install >> cd /usr/src/sys/i386/conf >> config MYKERNEL >> cd ../compile/MYKERNEL >> make cleandepend && make depend >> make all >> make install >> reboot >> . >> . >> . >> kldload acpi_hp >> cat /dev/wmistat >> sysctl -a | grep acpi_hp.0 >> sysctl dev.acpi_hp.0.als = 0 >> cat /dev/hpcmi >> sysctl dev.acpi_hp.0.cmi_detail=7 >> cat /dev/hpcmi >> >> It would be nice to get some feedback on this and maybe someone else can >> implement vendor specific ACPI modules for other WMI based laptops now. > > I tested committed version on 8.0. > What about making following verbose device_printfs optional: > Wireless status is 0xXXXX , (new_wlan_status is 0xXXXX), > (new_wwan_status is 0xXXXX) > > > # cat /dev/hpcmi > > doesn't show Enabled/Disabled/Values. > What does cat /dev/hpcmi show on your system? Did you try modifying dev.acpi_hp.0.cmi_detail (see man acpi_hp(4))? What is in /var/log/messages when loading the driver? From owner-freebsd-acpi@FreeBSD.ORG Wed Jun 24 06:21:32 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D09C81065673; Wed, 24 Jun 2009 06:21:32 +0000 (UTC) (envelope-from onemda@gmail.com) Received: from mail-bw0-f209.google.com (mail-bw0-f209.google.com [209.85.218.209]) by mx1.freebsd.org (Postfix) with ESMTP id 24CBD8FC19; Wed, 24 Jun 2009 06:21:31 +0000 (UTC) (envelope-from onemda@gmail.com) Received: by bwz5 with SMTP id 5so488533bwz.43 for ; Tue, 23 Jun 2009 23:21:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=iP2PGDFdljx39Iy3RpfPwmLh1P1I30k2OcODcFf2Z6s=; b=DuOh0EwpI3zfh++iZ7dkDD3FZDg2nhzpIza17/cT03Bs5TO6zDIdLy3Qz2Q0qtN9aL hrTJJPhq6QlcfoLo2yQ6MwWNIUT6X7n0Xs3WodkhlaaPABYQHFpU7bNq9wLBGjbHFEgD cDg/+aqmQWOT1avMMUXGD8wdU6BM+S/r7mEaE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; b=Xz5QgjRsFbqp+RGDnuhImGB9LeBkjAdnmAh/7d8By7J6HsvqyK1Ze3PuFES8fA93Tj XEQQjKMTrPRHajp2CAtuHYcTv+GD5F2l7lLlun9lCtrVyy28xhGg/54RLHGqFI8K9nQ+ r/heMzNPLuWVsCRRX1YKHhaB9Md5N33KB6d3Y= MIME-Version: 1.0 Received: by 10.204.72.15 with SMTP id k15mr924312bkj.14.1245823023612; Tue, 23 Jun 2009 22:57:03 -0700 (PDT) In-Reply-To: <4A3E1784.2050406@bindone.de> References: <4A3E1784.2050406@bindone.de> Date: Wed, 24 Jun 2009 07:57:03 +0200 Message-ID: <3a142e750906232257y4b1e255en9374c05079f04520@mail.gmail.com> From: "Paul B. Mahol" To: Michael Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: c.r.n.a@wanadoo.fr, freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jun 2009 06:21:33 -0000 On 6/21/09, Michael wrote: > Hello, > > I wrote two new acpi modules last year and finally found the time to fix > them, add some missing features and write man pages. > > This is the first time I'm writing kernel code for FreeBSD, so please > excuse me if I failed to apply to all style conventions (I tried to > follow style(9) as closely as possible). > > acpi_wmi is an ACPI to WMI mapping driver (this is used by HP and Acer > notebooks and potentially others), so this could also be used to > implement additional drivers on (see for more details on WMI and ACPI: > http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx). > It provides /dev/wmistat, example output: > cat /dev/wmistat > GUID INST EXPE METH STR EVENT OID > {5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA > {95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - > {2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - > {05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB > {1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA > {2D114B49-2DFB-4130-B8FE-4A3C09E75133} 57 NO NO NO NO BC > {988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 20 NO NO NO NO BD > {14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE > {322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF > {8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG > {8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH > {8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI > > acpi_hp is a driver that uses acpi_wmi to provide HP specific features. > These include: > - Activate/deactivate WLAN > - Activate/deactivate WWAN > - Activate/deactivate Bluetooth > - Auto activate/deactiavte based on hw radio status > - Devd notifications > - On air status for different > - Controls ambient light sensor > - Get docking status > - Read BIOS settings through /dev/hpcmi, example output: > Flash Media Reader Disable > USB Ports including Express Card slot Enable > 1394 Port Enable > Cardbus Slot Disable > Express Card Slot Disable > F9, F10 and F12 Delay(Sec) 0 > USB Device Detection Delay (Sec) 0 > Multiboot Enable > Express Boot Popup Delay(Sec) 0 > CD-ROM Boot Enable > Floppy Boot Disable > Internal Network Adapter Boot Disable > Internal Network Adapter Boot Mode PXE > Swap Fn/Ctrl Key Disable > USB Legacy Support Disable > Parallel Port Mode ECP > ... > > The man pages included in the patch (man acpi_hp / man acpi_wmi) give > you detailed information about all sysctls and devices. > > The patch attached (acpi_wmi_and_acpi_hp.patch) has been tested against > 7.2-RELEASE and everything compiles cleanly, although my tests have been > on 8-CURRENT (but the snapshot is older than 7.2), so I expect this to > work ok on 7.2. The patch might fail against CURRENT though, this is why > I also attached patches.tgz, which contains individual patches per file. > I only tested this on i386 and the patch only changes i386 specific > things (I have no idea if this could possibly work on amd64, especially > because all the other acpi_support modules seem to be i386 only). Also > note, that I could only test this on my own machine (HP Compaq 8510p), > which features WLAN/BT/WLAN, so I don't know if the readings will be > sane if your machine doesn't feature a WWAN chip. In theory this should > work for many different HP models. > > Installation instructions (replace MYKERNEL with your kernel name): > > mkdir /usr/src/sys/modules/acpi/acpi_wmi > mkdir /usr/src/sys/modules/acpi/acpi_hp > patch -d /usr/src < acpi_wmi_and_acpi_hp.patch > cd /usr/src/share/man/man4/man4.i386 > make all && make install > cd /usr/src/sys/i386/conf > config MYKERNEL > cd ../compile/MYKERNEL > make cleandepend && make depend > make all > make install > reboot > . > . > . > kldload acpi_hp > cat /dev/wmistat > sysctl -a | grep acpi_hp.0 > sysctl dev.acpi_hp.0.als = 0 > cat /dev/hpcmi > sysctl dev.acpi_hp.0.cmi_detail=7 > cat /dev/hpcmi > > It would be nice to get some feedback on this and maybe someone else can > implement vendor specific ACPI modules for other WMI based laptops now. I tested committed version on 8.0. What about making following verbose device_printfs optional: Wireless status is 0xXXXX , (new_wlan_status is 0xXXXX), (new_wwan_status is 0xXXXX) # cat /dev/hpcmi doesn't show Enabled/Disabled/Values. -- Paul From owner-freebsd-acpi@FreeBSD.ORG Wed Jun 24 06:53:17 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3B45E106566C for ; Wed, 24 Jun 2009 06:53:17 +0000 (UTC) (envelope-from onemda@gmail.com) Received: from mail-bw0-f209.google.com (mail-bw0-f209.google.com [209.85.218.209]) by mx1.freebsd.org (Postfix) with ESMTP id 9197B8FC1D for ; Wed, 24 Jun 2009 06:53:16 +0000 (UTC) (envelope-from onemda@gmail.com) Received: by bwz5 with SMTP id 5so499192bwz.43 for ; Tue, 23 Jun 2009 23:53:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=lwtERHREwznbYRtbaaKtY6IxQt6AWoiRS2uTcRYTVS8=; b=tpWaeUrwBtio9FMui0npv2u8wPUVycpd1xXqCMgDJm4b5iS7rgKcH9F1RsKFnbbeyh tKweo5/hpSNTvpa+/CkDHnNCg351azkuomQ7oF0aPKWNmxEGorFT8NbL5fDeQDDBfgMM E4aED96jBeJPFYUIkdXbKHeOTtFf3tMu7iKzM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; b=NRdpqe6YOnE6cGNAHvokaWwb/la/ivbLB6OYveRqBdn7LF0kxy1oEVzT1ZhfUtgDy9 Fu/f7wH8E53MZ00AD5RYdRNDEnnYixKXhcWlBnKHtpj5j3QSVrHsR39Wu0/uYoiwsWdP tUYjcJZsmf/bE4rQ5N4e+3/2NrkdW5ovliksg= MIME-Version: 1.0 Received: by 10.204.62.68 with SMTP id w4mr934088bkh.122.1245826395385; Tue, 23 Jun 2009 23:53:15 -0700 (PDT) In-Reply-To: <4A41C2CF.4020205@bindone.de> References: <4A3E1784.2050406@bindone.de> <3a142e750906232257y4b1e255en9374c05079f04520@mail.gmail.com> <4A41C2CF.4020205@bindone.de> Date: Wed, 24 Jun 2009 08:53:15 +0200 Message-ID: <3a142e750906232353g37b5f001p89948a2fe6a3e66e@mail.gmail.com> From: "Paul B. Mahol" To: Michael Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jun 2009 06:53:17 -0000 On 6/24/09, Michael wrote: > Paul B. Mahol wrote: >> On 6/21/09, Michael wrote: >>> Hello, >>> >>> I wrote two new acpi modules last year and finally found the time to fix >>> them, add some missing features and write man pages. >>> >>> This is the first time I'm writing kernel code for FreeBSD, so please >>> excuse me if I failed to apply to all style conventions (I tried to >>> follow style(9) as closely as possible). >>> >>> acpi_wmi is an ACPI to WMI mapping driver (this is used by HP and Acer >>> notebooks and potentially others), so this could also be used to >>> implement additional drivers on (see for more details on WMI and ACPI: >>> http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx). >>> It provides /dev/wmistat, example output: >>> cat /dev/wmistat >>> GUID INST EXPE METH STR EVENT OID >>> {5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA >>> {95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - >>> {2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - >>> {05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB >>> {1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA >>> {2D114B49-2DFB-4130-B8FE-4A3C09E75133} 57 NO NO NO NO BC >>> {988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 20 NO NO NO NO BD >>> {14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE >>> {322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF >>> {8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG >>> {8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH >>> {8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI >>> >>> acpi_hp is a driver that uses acpi_wmi to provide HP specific features. >>> These include: >>> - Activate/deactivate WLAN >>> - Activate/deactivate WWAN >>> - Activate/deactivate Bluetooth >>> - Auto activate/deactiavte based on hw radio status >>> - Devd notifications >>> - On air status for different >>> - Controls ambient light sensor >>> - Get docking status >>> - Read BIOS settings through /dev/hpcmi, example output: >>> Flash Media Reader Disable >>> USB Ports including Express Card slot Enable >>> 1394 Port Enable >>> Cardbus Slot Disable >>> Express Card Slot Disable >>> F9, F10 and F12 Delay(Sec) 0 >>> USB Device Detection Delay (Sec) 0 >>> Multiboot Enable >>> Express Boot Popup Delay(Sec) 0 >>> CD-ROM Boot Enable >>> Floppy Boot Disable >>> Internal Network Adapter Boot Disable >>> Internal Network Adapter Boot Mode PXE >>> Swap Fn/Ctrl Key Disable >>> USB Legacy Support Disable >>> Parallel Port Mode ECP >>> ... >>> >>> The man pages included in the patch (man acpi_hp / man acpi_wmi) give >>> you detailed information about all sysctls and devices. >>> >>> The patch attached (acpi_wmi_and_acpi_hp.patch) has been tested against >>> 7.2-RELEASE and everything compiles cleanly, although my tests have been >>> on 8-CURRENT (but the snapshot is older than 7.2), so I expect this to >>> work ok on 7.2. The patch might fail against CURRENT though, this is why >>> I also attached patches.tgz, which contains individual patches per file. >>> I only tested this on i386 and the patch only changes i386 specific >>> things (I have no idea if this could possibly work on amd64, especially >>> because all the other acpi_support modules seem to be i386 only). Also >>> note, that I could only test this on my own machine (HP Compaq 8510p), >>> which features WLAN/BT/WLAN, so I don't know if the readings will be >>> sane if your machine doesn't feature a WWAN chip. In theory this should >>> work for many different HP models. >>> >>> Installation instructions (replace MYKERNEL with your kernel name): >>> >>> mkdir /usr/src/sys/modules/acpi/acpi_wmi >>> mkdir /usr/src/sys/modules/acpi/acpi_hp >>> patch -d /usr/src < acpi_wmi_and_acpi_hp.patch >>> cd /usr/src/share/man/man4/man4.i386 >>> make all && make install >>> cd /usr/src/sys/i386/conf >>> config MYKERNEL >>> cd ../compile/MYKERNEL >>> make cleandepend && make depend >>> make all >>> make install >>> reboot >>> . >>> . >>> . >>> kldload acpi_hp >>> cat /dev/wmistat >>> sysctl -a | grep acpi_hp.0 >>> sysctl dev.acpi_hp.0.als = 0 >>> cat /dev/hpcmi >>> sysctl dev.acpi_hp.0.cmi_detail=7 >>> cat /dev/hpcmi >>> >>> It would be nice to get some feedback on this and maybe someone else can >>> implement vendor specific ACPI modules for other WMI based laptops now. >> >> I tested committed version on 8.0. >> What about making following verbose device_printfs optional: >> Wireless status is 0xXXXX , (new_wlan_status is 0xXXXX), >> (new_wwan_status is 0xXXXX) >> >> >> # cat /dev/hpcmi >> >> doesn't show Enabled/Disabled/Values. >> > What does cat /dev/hpcmi show on your system? > Did you try modifying dev.acpi_hp.0.cmi_detail (see man acpi_hp(4))? > What is in /var/log/messages when loading the driver? > cat /dev/wmistat GUID INST EXPE METH STR EVENT OID {5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA {95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - {2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - {05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB {1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA {2D114B49-2DFB-4130-B8FE-4A3C09E75133} 41 NO NO NO NO BC {988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 14 NO NO NO NO BD {14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE {322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF {8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG {8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH {8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI > cat /dev/hpcmi Serial Port Infrared Port Parallel Port Flash Media Reader USB Ports 1394 Port Cardbus Slot Express Card Slot F9, F10 and F12 Delay(Sec) Multiboot Express Boot Popup Delay(Sec) CD-ROM Boot Floppy Boot Internal Network Adapter Boot Internal Network Adapter Boot Mode Swap Fn/Ctrl Key HDD Translation Mode Virtualization Technology USB Legacy Support Parallel Port Mode BIOS DMA Data Transfers Fan Always on while on AC Power Data Execution Prevention LAN Power Saving SATA Native Mode Dual Core CPU Secondary Battery Fast Charge Embedded WLAN Device Radio Embedded WWAN Device Radio Ambient Light Sensor Embedded Bluetooth Device Radio LAN/WLAN Switching Wake on LAN acpi_wmi0: on acpi0 acpi_hp0: on acpi0 acpi_hp0: HP event GUID detected, installing event handler acpi_hp0: HP CMI GUID detected acpi_wmi0: Wireless status is c0a0f2b acpi_wmi0: WLAN on air changed to 1 (new_wlan_status is 256) acpi_wmi0: Wireless status is c02062b acpi_wmi0: WLAN on air changed to 0 (new_wlan_status is 0) acpi_wmi0: Wireless status is c0a0f2b acpi_wmi0: WLAN on air changed to 1 (new_wlan_status is 256) ACPI Error: Field [C2CA] at 336 exceeds Buffer [C281] size 328 (bits) 20090521 dsopcode-697 ACPI Error (psparse-0633): Method parse/execution failed [\\_SB_.C241.WQBC] (Node 0xc3dceb20), AE_AML_BUFFER_LIMIT -- Paul From owner-freebsd-acpi@FreeBSD.ORG Wed Jun 24 08:29:29 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4CE45106567B for ; Wed, 24 Jun 2009 08:29:29 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 8E5438FC1E for ; Wed, 24 Jun 2009 08:29:28 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 96470 invoked by uid 89); 24 Jun 2009 08:29:26 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.167.13) by mail.bindone.de with ESMTPA; 24 Jun 2009 08:29:26 -0000 Message-ID: <4A41E39E.1090208@bindone.de> Date: Wed, 24 Jun 2009 10:28:14 +0200 From: Michael User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: "Paul B. Mahol" References: <4A3E1784.2050406@bindone.de> <3a142e750906232257y4b1e255en9374c05079f04520@mail.gmail.com> <4A41C2CF.4020205@bindone.de> <3a142e750906232353g37b5f001p89948a2fe6a3e66e@mail.gmail.com> In-Reply-To: <3a142e750906232353g37b5f001p89948a2fe6a3e66e@mail.gmail.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jun 2009 08:29:29 -0000 Paul B. Mahol wrote: > On 6/24/09, Michael wrote: >> Paul B. Mahol wrote: >>> On 6/21/09, Michael wrote: >>>> Hello, >>>> >>>> I wrote two new acpi modules last year and finally found the time to fix >>>> them, add some missing features and write man pages. >>>> >>>> This is the first time I'm writing kernel code for FreeBSD, so please >>>> excuse me if I failed to apply to all style conventions (I tried to >>>> follow style(9) as closely as possible). >>>> >>>> acpi_wmi is an ACPI to WMI mapping driver (this is used by HP and Acer >>>> notebooks and potentially others), so this could also be used to >>>> implement additional drivers on (see for more details on WMI and ACPI: >>>> http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx). >>>> It provides /dev/wmistat, example output: >>>> cat /dev/wmistat >>>> GUID INST EXPE METH STR EVENT OID >>>> {5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA >>>> {95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - >>>> {2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - >>>> {05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB >>>> {1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA >>>> {2D114B49-2DFB-4130-B8FE-4A3C09E75133} 57 NO NO NO NO BC >>>> {988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 20 NO NO NO NO BD >>>> {14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE >>>> {322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF >>>> {8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG >>>> {8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH >>>> {8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI >>>> >>>> acpi_hp is a driver that uses acpi_wmi to provide HP specific features. >>>> These include: >>>> - Activate/deactivate WLAN >>>> - Activate/deactivate WWAN >>>> - Activate/deactivate Bluetooth >>>> - Auto activate/deactiavte based on hw radio status >>>> - Devd notifications >>>> - On air status for different >>>> - Controls ambient light sensor >>>> - Get docking status >>>> - Read BIOS settings through /dev/hpcmi, example output: >>>> Flash Media Reader Disable >>>> USB Ports including Express Card slot Enable >>>> 1394 Port Enable >>>> Cardbus Slot Disable >>>> Express Card Slot Disable >>>> F9, F10 and F12 Delay(Sec) 0 >>>> USB Device Detection Delay (Sec) 0 >>>> Multiboot Enable >>>> Express Boot Popup Delay(Sec) 0 >>>> CD-ROM Boot Enable >>>> Floppy Boot Disable >>>> Internal Network Adapter Boot Disable >>>> Internal Network Adapter Boot Mode PXE >>>> Swap Fn/Ctrl Key Disable >>>> USB Legacy Support Disable >>>> Parallel Port Mode ECP >>>> ... >>>> >>>> The man pages included in the patch (man acpi_hp / man acpi_wmi) give >>>> you detailed information about all sysctls and devices. >>>> >>>> The patch attached (acpi_wmi_and_acpi_hp.patch) has been tested against >>>> 7.2-RELEASE and everything compiles cleanly, although my tests have been >>>> on 8-CURRENT (but the snapshot is older than 7.2), so I expect this to >>>> work ok on 7.2. The patch might fail against CURRENT though, this is why >>>> I also attached patches.tgz, which contains individual patches per file. >>>> I only tested this on i386 and the patch only changes i386 specific >>>> things (I have no idea if this could possibly work on amd64, especially >>>> because all the other acpi_support modules seem to be i386 only). Also >>>> note, that I could only test this on my own machine (HP Compaq 8510p), >>>> which features WLAN/BT/WLAN, so I don't know if the readings will be >>>> sane if your machine doesn't feature a WWAN chip. In theory this should >>>> work for many different HP models. >>>> >>>> Installation instructions (replace MYKERNEL with your kernel name): >>>> >>>> mkdir /usr/src/sys/modules/acpi/acpi_wmi >>>> mkdir /usr/src/sys/modules/acpi/acpi_hp >>>> patch -d /usr/src < acpi_wmi_and_acpi_hp.patch >>>> cd /usr/src/share/man/man4/man4.i386 >>>> make all && make install >>>> cd /usr/src/sys/i386/conf >>>> config MYKERNEL >>>> cd ../compile/MYKERNEL >>>> make cleandepend && make depend >>>> make all >>>> make install >>>> reboot >>>> . >>>> . >>>> . >>>> kldload acpi_hp >>>> cat /dev/wmistat >>>> sysctl -a | grep acpi_hp.0 >>>> sysctl dev.acpi_hp.0.als = 0 >>>> cat /dev/hpcmi >>>> sysctl dev.acpi_hp.0.cmi_detail=7 >>>> cat /dev/hpcmi >>>> >>>> It would be nice to get some feedback on this and maybe someone else can >>>> implement vendor specific ACPI modules for other WMI based laptops now. >>> I tested committed version on 8.0. >>> What about making following verbose device_printfs optional: >>> Wireless status is 0xXXXX , (new_wlan_status is 0xXXXX), >>> (new_wwan_status is 0xXXXX) >>> >>> >>> # cat /dev/hpcmi >>> >>> doesn't show Enabled/Disabled/Values. >>> >> What does cat /dev/hpcmi show on your system? >> Did you try modifying dev.acpi_hp.0.cmi_detail (see man acpi_hp(4))? >> What is in /var/log/messages when loading the driver? > >> cat /dev/wmistat > GUID INST EXPE METH STR EVENT OID > {5FB7F034-2C63-45E9-BE91-3D44E2C707E4} 1 NO WMAA NO NO AA > {95F24279-4D7B-4334-9387-ACCDC67EF61C} 1 NO NO NO 0x80+ - > {2B814318-4BE8-4707-9D84-A190A859B5D0} 1 NO NO NO 0xA0 - > {05901221-D566-11D1-B2F0-00A0C9062910} 1 NO NO NO NO AB > {1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E} 1 NO WMBA NO NO BA > {2D114B49-2DFB-4130-B8FE-4A3C09E75133} 41 NO NO NO NO BC > {988D08E3-68F4-4C35-AF3E-6A1B8106F83C} 14 NO NO NO NO BD > {14EA9746-CE1F-4098-A0E0-7045CB4DA745} 1 NO NO NO NO BE > {322F2028-0F84-4901-988E-015176049E2D} 2 NO NO NO NO BF > {8232DE3D-663D-4327-A8F4-E293ADB9BF05} 0 NO NO NO NO BG > {8F1F6436-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BH > {8F1F6435-9F42-42C8-BADC-0E9424F20C9A} 0 NO NO NO NO BI > >> cat /dev/hpcmi > Serial Port > Infrared Port > Parallel Port > Flash Media Reader > USB Ports > 1394 Port > Cardbus Slot > Express Card Slot > F9, F10 and F12 Delay(Sec) > Multiboot > Express Boot Popup Delay(Sec) > CD-ROM Boot > Floppy Boot > Internal Network Adapter Boot > Internal Network Adapter Boot Mode > Swap Fn/Ctrl Key > HDD Translation Mode > Virtualization Technology > USB Legacy Support > Parallel Port Mode > BIOS DMA Data Transfers > Fan Always on while on AC Power > Data Execution Prevention > LAN Power Saving > SATA Native Mode > Dual Core CPU > Secondary Battery Fast Charge > Embedded WLAN Device Radio > Embedded WWAN Device Radio > Ambient Light Sensor > Embedded Bluetooth Device Radio > LAN/WLAN Switching > Wake on LAN > > > acpi_wmi0: on acpi0 > acpi_hp0: on acpi0 > acpi_hp0: HP event GUID detected, installing event handler > acpi_hp0: HP CMI GUID detected > acpi_wmi0: Wireless status is c0a0f2b > acpi_wmi0: WLAN on air changed to 1 (new_wlan_status is 256) > acpi_wmi0: Wireless status is c02062b > acpi_wmi0: WLAN on air changed to 0 (new_wlan_status is 0) > acpi_wmi0: Wireless status is c0a0f2b > acpi_wmi0: WLAN on air changed to 1 (new_wlan_status is 256) > ACPI Error: Field [C2CA] at 336 exceeds Buffer [C281] size 328 (bits) > 20090521 dsopcode-697 > ACPI Error (psparse-0633): Method parse/execution failed > [\\_SB_.C241.WQBC] (Node 0xc3dceb20), AE_AML_BUFFER_LIMIT > Interesting... can you send me your DSDT? The last error message is definitely caused by a bug in the DSDT, but that that shouldn't prevent the values from showing up (I assume you tried on a wide terminal). Can you send me the following informations: 1. Output of cat /dev/wmistat (cat /dev/wmistat >/tmp/wmistat.out) 2. Output of cat /dev/hpcmi with cmi_detail set to 7 (sysctl dev.acpi_hp.0.cmi_detail=7; cat /dev/hpcmi >/tmp/hpcmi.out) 3. Your DSDT (acpidump -dt > /tmp/my_computer.asl) thanks Michael From owner-freebsd-acpi@FreeBSD.ORG Wed Jun 24 17:44:39 2009 Return-Path: Delivered-To: freebsd-acpi@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6BAC7106566C; Wed, 24 Jun 2009 17:44:39 +0000 (UTC) (envelope-from linimon@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 40CB38FC18; Wed, 24 Jun 2009 17:44:39 +0000 (UTC) (envelope-from linimon@FreeBSD.org) Received: from freefall.freebsd.org (linimon@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.3/8.14.3) with ESMTP id n5OHid3u037611; Wed, 24 Jun 2009 17:44:39 GMT (envelope-from linimon@freefall.freebsd.org) Received: (from linimon@localhost) by freefall.freebsd.org (8.14.3/8.14.3/Submit) id n5OHidnh037607; Wed, 24 Jun 2009 17:44:39 GMT (envelope-from linimon) Date: Wed, 24 Jun 2009 17:44:39 GMT Message-Id: <200906241744.n5OHidnh037607@freefall.freebsd.org> To: linimon@FreeBSD.org, freebsd-bugs@FreeBSD.org, freebsd-acpi@FreeBSD.org From: linimon@FreeBSD.org Cc: Subject: Re: i386/136008: [acpi] Dell Vostro 1310 will not shutdown (Requires user intervention) X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jun 2009 17:44:39 -0000 Old Synopsis: Dell Vostro 1310 will not shutdown (Requires user intervention) New Synopsis: [acpi] Dell Vostro 1310 will not shutdown (Requires user intervention) Responsible-Changed-From-To: freebsd-bugs->freebsd-acpi Responsible-Changed-By: linimon Responsible-Changed-When: Wed Jun 24 17:43:59 UTC 2009 Responsible-Changed-Why: Sounds like an ACPI problem. http://www.freebsd.org/cgi/query-pr.cgi?pr=136008 From owner-freebsd-acpi@FreeBSD.ORG Thu Jun 25 19:43:46 2009 Return-Path: Delivered-To: acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 241BB1065673 for ; Thu, 25 Jun 2009 19:43:46 +0000 (UTC) (envelope-from robert.moore@intel.com) Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by mx1.freebsd.org (Postfix) with ESMTP id F2E2F8FC08 for ; Thu, 25 Jun 2009 19:43:45 +0000 (UTC) (envelope-from robert.moore@intel.com) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 25 Jun 2009 12:43:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.42,292,1243839600"; d="scan'208";a="158565063" Received: from orsmsx602.amr.corp.intel.com ([10.22.226.211]) by azsmga001.ch.intel.com with ESMTP; 25 Jun 2009 12:43:45 -0700 Received: from orsmsx503.amr.corp.intel.com ([10.22.226.47]) by orsmsx602.amr.corp.intel.com ([10.22.226.211]) with mapi; Thu, 25 Jun 2009 12:43:45 -0700 From: "Moore, Robert" To: "Moore, Robert" Date: Thu, 25 Jun 2009 12:43:43 -0700 Thread-Topic: ACPICA version 20090625 released Thread-Index: Acn1zT8yCHGOT3R2Qp24gyMkukN8Zg== Message-ID: <4911F71203A09E4D9981D27F9D8308582E926C8A@orsmsx503.amr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailman-Approved-At: Fri, 26 Jun 2009 08:09:20 +0000 Cc: Subject: ACPICA version 20090625 released X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Jun 2009 19:43:46 -0000 25 June 2009. Summary of changes for version 20090625: This release is available at www.acpica.org/downloads The ACPI 4.0 Specification was released on June 16 and is available at www.= acpi.info. ACPICA implementation of ACPI 4.0 is underway and will continue = for the next few releases. 1) ACPI CA Core Subsystem: ACPI 4.0: Implemented interpreter support for the IPMI operation region add= ress space. Includes support for bi-directional data buffers and an IPMI ad= dress space handler (to be installed by an IPMI device driver.) ACPICA BZ 7= 73. Lin Ming. ACPI 4.0: Added changes for existing ACPI tables - FACS and SRAT. Includes = support in both the header files and the disassembler. Completed a major update for the AcpiGetObjectInfo external interface. Chan= ges include: - Support for variable, unlimited length HID, UID, and CID strings. - Support Processor objects the same as Devices (HID,UID,CID,ADR,STA, etc.= ) - Call the _SxW power methods on behalf of a device object. - Determine if a device is a PCI root bridge. - Change the ACPI_BUFFER parameter to ACPI_DEVICE_INFO. These changes will require an update to all callers of this interface. See = the updated ACPICA Programmer Reference for details. One new source file ha= s been added - utilities/utids.c. ACPICA BZ 368, 780. Updated the AcpiRead and AcpiWrite external interfaces to support 64-bit tr= ansfers. The Value parameter has been extended from 32 bits to 64 bits in o= rder to support new ACPI 4.0 tables. These changes will require an update t= o all callers of these interfaces. See the ACPICA Programmer Reference for = details. ACPICA BZ 768. Fixed several problems with AcpiAttachData. The handler was not invoked whe= n the host node was deleted. The data sub-object was not automatically dele= ted when the host node was deleted. The interface to the handler had an unu= sed parameter, this was removed. ACPICA BZ 778. Enhanced the function that dumps ACPI table headers. All non-printable char= acters in the string fields are now replaced with '?' (Signature, OemId, Oe= mTableId, and CompilerId.) ACPI tables with non-printable characters in the= se fields are occasionally seen in the field. ACPICA BZ 788. Fixed a problem with predefined method repair code where the code that atte= mpts to repair/convert an object of incorrect type is only executed on the = first time the predefined method is called. The mechanism that disables war= nings on subsequent calls was interfering with the repair mechanism. ACPICA= BZ 781. Fixed a possible memory leak in the predefined validation/repair code when = a buffer is automatically converted to an expected string object. Removed obsolete 16-bit files from the distribution and from the current gi= t tree head. ACPICA BZ 776. Example Code and Data Size: These are the sizes for the OS-independent acpi= ca.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The debug = version of the code includes the debug output trace mechanism and has a muc= h larger code and data size. Previous Release: Non-Debug Version: 83.4K Code, 17.5K Data, 100.9K Total Debug Version: 158.9K Code, 50.0K Data, 208.9K Total Current Release: Non-Debug Version: 84.7K Code, 17.8K Data, 102.5K Total Debug Version: 160.5K Code, 50.6K Data, 211.1K Total 2) iASL Compiler/Disassembler and Tools: ACPI 4.0: iASL and Disassembler - implemented support for the new IPMI oper= ation region keyword. ACPICA BZ 771, 772. Lin Ming. ACPI 4.0: iASL - implemented compile-time validation support for all new pr= edefined names and control methods (31 total). ACPICA BZ 769. From owner-freebsd-acpi@FreeBSD.ORG Fri Jun 26 08:43:17 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A37A21065673 for ; Fri, 26 Jun 2009 08:43:17 +0000 (UTC) (envelope-from patttern@gmail.com) Received: from mail-fx0-f218.google.com (mail-fx0-f218.google.com [209.85.220.218]) by mx1.freebsd.org (Postfix) with ESMTP id 33D888FC15 for ; Fri, 26 Jun 2009 08:43:17 +0000 (UTC) (envelope-from patttern@gmail.com) Received: by fxm18 with SMTP id 18so619595fxm.43 for ; Fri, 26 Jun 2009 01:43:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:date:message-id:subject :from:to:content-type; bh=65v0qADD+Ca1rnVsm/WewflhrA8Kcl3S7L4XY5053Ng=; b=HRKQgcM2XM4DzuJ06Yvotlzl0bz2Tqzc49+5NjGbhguTiE80e8VnU9O2eOf4WR4WaV 0yGi5L2SG6Sy+VSotRL6Y73oltAiVDw/c21ew9Qkc8DtYXwt0w4FuJwnkR+M9jLj0e4d G5xnDwYn0O9BbLImxHAbYd7HEqzI6mvsCVZFQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=PWNeJvXYdYFOJQnocqVP9dUISl76bEy9Hl0NTGh1YOoBDUE4EJG73xXsuAC6Wx1yPb qJmF/FR8Ndd1vsmCibKsQvLX4InCMVssVzJ3CKOyhs5gxvn6nqkFd/i6wsuNNl+YjLz3 d0H73Ks4Ea31u5s1vbPLNGGXqvYtlm1q0V3vw= MIME-Version: 1.0 Received: by 10.204.57.18 with SMTP id a18mr3391160bkh.19.1246004110151; Fri, 26 Jun 2009 01:15:10 -0700 (PDT) Date: Fri, 26 Jun 2009 12:15:10 +0400 Message-ID: <107cc88f0906260115y61785babhfd7f36ec7d0aa082@mail.gmail.com> From: Pattern To: freebsd-acpi@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Re: i386/136008: [acpi] Dell Vostro 1310 will not shutdown X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Jun 2009 08:43:19 -0000 Can you show iasl log? # iasl dburkland-DellVostro1310.asl > iasl.log 2009/6/25 > http://www.freebsd.org/cgi/query-pr.cgi?pr=136008 > > From owner-freebsd-acpi@FreeBSD.ORG Fri Jun 26 16:39:03 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EDB851065670 for ; Fri, 26 Jun 2009 16:39:03 +0000 (UTC) (envelope-from dan@dburkland.com) Received: from na3sys009aob109.obsmtp.com (na3sys009aob109.obsmtp.com [74.125.149.200]) by mx1.freebsd.org (Postfix) with SMTP id A7D408FC1E for ; Fri, 26 Jun 2009 16:39:03 +0000 (UTC) (envelope-from dan@dburkland.com) Received: from source ([173.8.114.137]) (using TLSv1) by na3sys009aob109.postini.com ([74.125.148.12]) with SMTP ID DSNKSkT5pR2ws12wQkNpI+jqhyoZLvfqeZCO@postini.com; Fri, 26 Jun 2009 09:39:03 PDT Received: from mail.dburk.local ([10.0.0.4]) by mail ([10.0.0.4]) with mapi; Fri, 26 Jun 2009 11:39:04 -0500 From: Daniel Burkland To: "freebsd-acpi@freebsd.org" Date: Fri, 26 Jun 2009 11:39:03 -0500 Thread-Topic: i386/136008: [acpi] Dell Vostro 1310 will not shutdown Thread-Index: AQHJ9nyd3hm7gaE7bk2Ws1F4SrpNbw== Message-ID: <9BF0E9EFFF8AD245AAB6AAB1542D95967CF975D1@mail> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: i386/136008: [acpi] Dell Vostro 1310 will not shutdown X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Jun 2009 16:39:04 -0000 Here is the output from "iasl dburkland-DellVostro1310.asl > iasl.log" http://jperzel.net/vostro1310/current/iasl.log http://jperzel.net/vostro1310/current/iasl.core Thanks again. Dan= From owner-freebsd-acpi@FreeBSD.ORG Sat Jun 27 11:25:06 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1C1AF1065670 for ; Sat, 27 Jun 2009 11:25:06 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 3618E8FC20 for ; Sat, 27 Jun 2009 11:25:03 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 47870 invoked by uid 89); 27 Jun 2009 11:25:02 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.167.4) by mail.bindone.de with ESMTPA; 27 Jun 2009 11:25:02 -0000 Message-ID: <4A46018B.90709@bindone.de> Date: Sat, 27 Jun 2009 13:24:59 +0200 From: Michael Gmelin User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: Rui Paulo , freebsd-acpi@freebsd.org Content-Type: multipart/mixed; boundary="------------090600020803080001000309" Cc: "Paul B. Mahol" Subject: Patches to acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Jun 2009 11:25:06 -0000 This is a multi-part message in MIME format. --------------090600020803080001000309 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hello, please find attached a patch to acpi_hp.c and acpi_hp.4 (and the complete files as well). This patch brings: - sysctl dev.acpi_hp.0.verbose to toggle debug output - A modification so this can deal with different array lengths when reading the CMI BIOS - now it works ok on HP Compaq nx7300 as well. - Document sysctl in man page - Add a section to manpage about hardware that has been reported to work ok Installation instructions (against latest CURRENT): patch -d /usr/src < /path/to/acpi_hp.patch cd /usr/src/sys/modules/acpi/acpi_hp make all && make install cd /usr/src/share/man/man4 make all && make install cheers Michael --------------090600020803080001000309 Content-Type: text/plain; name="acpi_hp.4" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="acpi_hp.4" .\" Copyright (c) 2009 Michael Gmelin .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" .Dd June 21, 2009 .Dt ACPI_HP 4 i386 .Os .Sh NAME .Nm acpi_hp .Nd "ACPI extras driver for HP laptops" .Sh SYNOPSIS To compile this driver into the kernel, place the following line in your kernel configuration file: .Bd -ragged -offset indent .Cd "device acpi_hp" .Ed .Pp Alternatively, to load the driver as a module at boot time, place the following line in .Xr loader.conf 5 : .Bd -literal -offset indent acpi_hp_load="YES" .Ed .Sh DESCRIPTION The .Nm driver provides support for ACPI-controlled features found on HP laptops that use a WMI enabled BIOS (e.g. HP Compaq 8510p and 6510p). .Pp The main purpose of this driver is to provide an interface, accessible via .Xr sysctl 8 , .Xr devd 8 and .Xr devfs 8 , through which applications can determine and change the status of various laptop components and BIOS settings. .Pp .Ss Xr devd 8 Ss Events Devd events received by .Xr devd 8 provide the following information: .Pp .Bl -tag -width "subsystem" -offset indent -compact .It system .Qq Li ACPI .It subsystem .Qq Li HP .It type The source of the event in the ACPI namespace. The value depends on the model. .It notify Event code (see below). .El .Pp Event codes: .Pp .Bl -tag -width "0xc0" -offset indent -compact .It Li 0xc0 WLAN on air status changed to 0 (not on air) .It Li 0xc1 WLAN on air status changed to 1 (on air) .It Li 0xd0 Bluetooth on air status changed to 0 (not on air) .It Li 0xd1 Bluetooth on air status changed to 1 (on air) .It Li 0xe0 WWAN on air status changed to 0 (not on air) .It Li 0xe1 WWAN on air status changed to 1 (on air) .El .Ss Xr devfs 8 Ss Device You can read /dev/hpcmi to see your current BIOS settings. The detail level can be adjusted by setting the sysctl .Va cmi_detail as described below. .Sh SYSCTL VARIABLES The following sysctls are currently implemented: .Ss WLAN: .Bl -tag -width indent .It Va dev.acpi_hp.0.wlan_enabled Toggle WLAN chip activity. .It Va dev.acpi_hp.0.wlan_radio (read-only) WLAN radio status (controlled by hardware switch) .It Va dev.acpi_hp.0.wlan_on_air (read-only) WLAN on air (chip enabled, hardware switch enabled + enabled in BIOS) .It Va dev.acpi_hp.0.wlan_enabled_if_radio_on If set to 1, the WLAN chip will be enabled if the radio is turned on .It Va dev.acpi_hp.0.wlan_disable_if_radio_off If set to 1, the WLAN chip will be disabled if the radio is turned off .El .Ss Bluetooth: .Bl -tag -width indent .It Va dev.acpi_hp.0.bt_enabled Toggle Bluetooth chip activity. .It Va dev.acpi_hp.0.bt_radio (read-only) Bluetooth radio status (controlled by hardware switch) .It Va dev.acpi_hp.0.bt_on_air (read-only) Bluetooth on air (chip enabled, hardware switch enabled + enabled in BIOS) .It Va dev.acpi_hp.0.bt_enabled_if_radio_on If set to 1, the Bluetooth chip will be enabled if the radio is turned on .It Va dev.acpi_hp.0.bt_disable_if_radio_off If set to 1, the Bluetooth chip will be disabled if the radio is turned off .El .Ss WWAN: .Bl -tag -width indent .It Va dev.acpi_hp.0.wwan_enabled Toggle WWAN chip activity. .It Va dev.acpi_hp.0.wwan_radio (read-only) WWAN radio status (controlled by hardware switch) .It Va dev.acpi_hp.0.wwan_on_air (read-only) WWAN on air (chip enabled, hardware switch enabled + enabled in BIOS) .It Va dev.acpi_hp.0.wwan_enabled_if_radio_on If set to 1, the WWAN chip will be enabled if the radio is turned on .It Va dev.acpi_hp.0.wwan_disable_if_radio_off If set to 1, the WWAN chip will be disabled if the radio is turned off .El .Ss Misc: .Bl -tag -width indent .It Va dev.acpi_hp.0.als_enabled Toggle ambient light sensor (ALS) .It Va dev.acpi_hp.0.display (read-only) Display status (bitmask) .It Va dev.acpi_hp.0.hdd_temperature (read-only) HDD temperature .It Va dev.acpi_hp.0.is_docked (read-only) Docking station status (1 if docked) .It Va dev.acpi_hp.0.cmi_detail Bitmask to control detail level in /dev/hpcmi output (values can be ORed). .Bl -tag -width "0x01" -offset indent -compact .It Li 0x01 Show path component of BIOS setting .It Li 0x02 Show a list of valid options for the BIOS setting .It Li 0x04 Show additional flags of BIOS setting (ReadOnly etc.) .El .It Va dev.acpi_hp.0.verbose (read-only) Set verbosity level .El .Pp Defaults for these sysctls can be set in .Xr sysctl.conf 5 . .Sh HARDWARE The .Nm driver has been reported to support the following hardware: .Pp .Bl -bullet -compact .It HP Compaq 8510p .It HP Compaq nx7300 .El .Pp It should work on most HP laptops that feature a WMI enabled BIOS. .Sh FILES .Bl -tag -width ".Pa /dev/hpcmi" .It Pa /dev/hpcmi Interface to read BIOS settings .El .Sh EXAMPLES The following can be added to .Xr devd.conf 5 in order disable the LAN interface when WLAN on air and reenable if it's not: .Bd -literal -offset indent notify 0 { match "system" "ACPI"; match "subsystem" "HP"; match "notify" "0xc0"; action "ifconfig em0 up"; }; notify 0 { match "system" "ACPI"; match "subsystem" "HP"; match "notify" "0xc1"; action "ifconfig em0 down"; }; .Ed .Pp Enable the ambient light sensor: .Bd -literal -offset indent sysctl dev.acpi_hp.0.als_enabled=1 .Ed .Pp Enable Bluetooth: .Bd -literal -offset indent sysctl dev.acpi_hp.0.bt_enabled=1 .Ed .Pp Get BIOS settings: .Bd -literal -offset indent cat /dev/hpcmi Serial Port Disable Infrared Port Enable Parallel Port Disable Flash Media Reader Disable USB Ports including Express Card slot Enable 1394 Port Enable Cardbus Slot Disable Express Card Slot Disable (...) .Ed .Pp Set maximum detail level for /dev/hpcmi output: .Bd -literal -offset indent sysctl dev.acpi_hp.0.cmi_detail=7 .Ed .Pp .Sh SEE ALSO .Xr acpi 4 , .Xr acpi_wmi 4 , .Xr sysctl.conf 5 , .Xr devd 8 , .Xr devfs 8 , .Xr sysctl 8 .Sh HISTORY The .Nm device driver first appeared in .Fx CURRENT . .Sh AUTHORS .An -nosplit The .Nm driver was written by .An Michael Gmelin Aq freebsd@grem.de .Pp It has been inspired by hp-wmi driver, which implements a subset of these features (hotkeys) on Linux. .Pp .Bl -tag -width indent .It HP CMI whitepaper: http://h20331.www2.hp.com/Hpsub/downloads/cmi_whitepaper.pdf .It wmi-hp for Linux: http://www.kernel.org .It WMI and ACPI: http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx .El .Pp This manual page was written by .An Michael Gmelin Aq freebsd@grem.de .Sh BUGS This driver is experimental and has only been tested on CURRENT i386 on an HP Compaq 8510p which featured all supported wireless devices (WWAN/BT/WLAN). Expect undefined results when operating on different hardware. .Pp Loading the driver is slow. Reading from /dev/hpcmi is even slower. .Pp Additional features like HP specific sensor readings or writing BIOS settings are not supported. --------------090600020803080001000309 Content-Type: text/plain; name="acpi_hp.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="acpi_hp.c" /*- * Copyright (c) 2009 Michael Gmelin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); /* * Driver for extra ACPI-controlled features found on HP laptops * that use a WMI enabled BIOS (e.g. HP Compaq 8510p and 6510p). * Allows to control and read status of integrated hardware and read * BIOS settings through CMI. * Inspired by the hp-wmi driver, which implements a subset of these * features (hotkeys) on Linux. * * HP CMI whitepaper: * http://h20331.www2.hp.com/Hpsub/downloads/cmi_whitepaper.pdf * wmi-hp for Linux: * http://www.kernel.org * WMI and ACPI: * http://www.microsoft.com/whdc/system/pnppwr/wmi/wmi-acpi.mspx */ #include "opt_acpi.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "acpi_wmi_if.h" #define _COMPONENT ACPI_OEM ACPI_MODULE_NAME("HP") #define ACPI_HP_WMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" #define ACPI_HP_WMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" #define ACPI_HP_WMI_CMI_GUID "2D114B49-2DFB-4130-B8FE-4A3C09E75133" #define ACPI_HP_WMI_DISPLAY_COMMAND 0x1 #define ACPI_HP_WMI_HDDTEMP_COMMAND 0x2 #define ACPI_HP_WMI_ALS_COMMAND 0x3 #define ACPI_HP_WMI_DOCK_COMMAND 0x4 #define ACPI_HP_WMI_WIRELESS_COMMAND 0x5 #define ACPI_HP_METHOD_WLAN_ENABLED 1 #define ACPI_HP_METHOD_WLAN_RADIO 2 #define ACPI_HP_METHOD_WLAN_ON_AIR 3 #define ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON 4 #define ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF 5 #define ACPI_HP_METHOD_BLUETOOTH_ENABLED 6 #define ACPI_HP_METHOD_BLUETOOTH_RADIO 7 #define ACPI_HP_METHOD_BLUETOOTH_ON_AIR 8 #define ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON 9 #define ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF 10 #define ACPI_HP_METHOD_WWAN_ENABLED 11 #define ACPI_HP_METHOD_WWAN_RADIO 12 #define ACPI_HP_METHOD_WWAN_ON_AIR 13 #define ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON 14 #define ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF 15 #define ACPI_HP_METHOD_ALS 16 #define ACPI_HP_METHOD_DISPLAY 17 #define ACPI_HP_METHOD_HDDTEMP 18 #define ACPI_HP_METHOD_DOCK 19 #define ACPI_HP_METHOD_CMI_DETAIL 20 #define ACPI_HP_METHOD_VERBOSE 21 #define HP_MASK_WWAN_ON_AIR 0x1000000 #define HP_MASK_BLUETOOTH_ON_AIR 0x10000 #define HP_MASK_WLAN_ON_AIR 0x100 #define HP_MASK_WWAN_RADIO 0x8000000 #define HP_MASK_BLUETOOTH_RADIO 0x80000 #define HP_MASK_WLAN_RADIO 0x800 #define HP_MASK_WWAN_ENABLED 0x2000000 #define HP_MASK_BLUETOOTH_ENABLED 0x20000 #define HP_MASK_WLAN_ENABLED 0x200 #define ACPI_HP_CMI_DETAIL_PATHS 0x01 #define ACPI_HP_CMI_DETAIL_ENUMS 0x02 #define ACPI_HP_CMI_DETAIL_FLAGS 0x04 struct acpi_hp_inst_seq_pair { UINT32 sequence; /* sequence number as suggested by cmi bios */ UINT8 instance; /* object instance on guid */ }; struct acpi_hp_softc { device_t dev; ACPI_HANDLE handle; device_t wmi_dev; int has_notify; /* notification GUID found */ int has_cmi; /* CMI GUID found */ int cmi_detail; /* CMI detail level (set by sysctl) */ int verbose; /* add debug output */ int wlan_enable_if_radio_on; /* set by sysctl */ int wlan_disable_if_radio_off; /* set by sysctl */ int bluetooth_enable_if_radio_on; /* set by sysctl */ int bluetooth_disable_if_radio_off; /* set by sysctl */ int wwan_enable_if_radio_on; /* set by sysctl */ int wwan_disable_if_radio_off; /* set by sysctl */ int was_wlan_on_air; /* last known WLAN on air status */ int was_bluetooth_on_air; /* last known BT on air status */ int was_wwan_on_air; /* last known WWAN on air status */ struct sysctl_ctx_list *sysctl_ctx; struct sysctl_oid *sysctl_tree; struct cdev *hpcmi_dev_t; /* hpcmi device handle */ struct sbuf hpcmi_sbuf; /* /dev/hpcmi output sbuf */ pid_t hpcmi_open_pid; /* pid operating on /dev/hpcmi */ int hpcmi_bufptr; /* current pointer position in /dev/hpcmi output buffer */ int cmi_order_size; /* size of cmi_order list */ struct acpi_hp_inst_seq_pair cmi_order[128]; /* list of CMI instances ordered by BIOS suggested sequence */ }; static struct { char *name; int method; char *description; int access; } acpi_hp_sysctls[] = { { .name = "wlan_enabled", .method = ACPI_HP_METHOD_WLAN_ENABLED, .description = "Enable/Disable WLAN (WiFi)", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wlan_radio", .method = ACPI_HP_METHOD_WLAN_RADIO, .description = "WLAN radio status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "wlan_on_air", .method = ACPI_HP_METHOD_WLAN_ON_AIR, .description = "WLAN radio ready to use (enabled and radio)", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "wlan_enable_if_radio_on", .method = ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON, .description = "Enable WLAN if radio is turned on", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wlan_disable_if_radio_off", .method = ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF, .description = "Disable WLAN if radio is turned off", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "bt_enabled", .method = ACPI_HP_METHOD_BLUETOOTH_ENABLED, .description = "Enable/Disable Bluetooth", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "bt_radio", .method = ACPI_HP_METHOD_BLUETOOTH_RADIO, .description = "Bluetooth radio status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "bt_on_air", .method = ACPI_HP_METHOD_BLUETOOTH_ON_AIR, .description = "Bluetooth radio ready to use" " (enabled and radio)", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "bt_enable_if_radio_on", .method = ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON, .description = "Enable bluetooth if radio is turned on", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "bt_disable_if_radio_off", .method = ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF, .description = "Disable bluetooth if radio is turned off", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wwan_enabled", .method = ACPI_HP_METHOD_WWAN_ENABLED, .description = "Enable/Disable WWAN (UMTS)", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wwan_radio", .method = ACPI_HP_METHOD_WWAN_RADIO, .description = "WWAN radio status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "wwan_on_air", .method = ACPI_HP_METHOD_WWAN_ON_AIR, .description = "WWAN radio ready to use (enabled and radio)", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "wwan_enable_if_radio_on", .method = ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON, .description = "Enable WWAN if radio is turned on", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "wwan_disable_if_radio_off", .method = ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF, .description = "Disable WWAN if radio is turned off", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "als_enabled", .method = ACPI_HP_METHOD_ALS, .description = "Enable/Disable ALS (Ambient light sensor)", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "display", .method = ACPI_HP_METHOD_DISPLAY, .description = "Display status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "hdd_temperature", .method = ACPI_HP_METHOD_HDDTEMP, .description = "HDD temperature", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "is_docked", .method = ACPI_HP_METHOD_DOCK, .description = "Docking station status", .access = CTLTYPE_INT | CTLFLAG_RD }, { .name = "cmi_detail", .method = ACPI_HP_METHOD_CMI_DETAIL, .description = "Details shown in CMI output " "(cat /dev/hpcmi)", .access = CTLTYPE_INT | CTLFLAG_RW }, { .name = "verbose", .method = ACPI_HP_METHOD_VERBOSE, .description = "Verbosity level", .access = CTLTYPE_INT | CTLFLAG_RW }, { NULL, 0, NULL, 0 } }; ACPI_SERIAL_DECL(hp, "HP ACPI-WMI Mapping"); static int acpi_hp_probe(device_t dev); static int acpi_hp_attach(device_t dev); static int acpi_hp_detach(device_t dev); static void acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc* sc); static int acpi_hp_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_hp_sysctl_set(struct acpi_hp_softc *sc, int method, int arg, int oldarg); static int acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method); static int acpi_hp_exec_wmi_command(device_t wmi_dev, int command, int is_write, int val); static void acpi_hp_notify(ACPI_HANDLE h, UINT32 notify, void *context); static int acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, UINT8 instance, char* outbuf, size_t outsize, UINT32* sequence, int detail); static void acpi_hp_hex_decode(char* buffer); static d_open_t acpi_hp_hpcmi_open; static d_close_t acpi_hp_hpcmi_close; static d_read_t acpi_hp_hpcmi_read; /* handler /dev/hpcmi device */ static struct cdevsw hpcmi_cdevsw = { .d_version = D_VERSION, .d_open = acpi_hp_hpcmi_open, .d_close = acpi_hp_hpcmi_close, .d_read = acpi_hp_hpcmi_read, .d_name = "hpcmi", }; static device_method_t acpi_hp_methods[] = { DEVMETHOD(device_probe, acpi_hp_probe), DEVMETHOD(device_attach, acpi_hp_attach), DEVMETHOD(device_detach, acpi_hp_detach), {0, 0} }; static driver_t acpi_hp_driver = { "acpi_hp", acpi_hp_methods, sizeof(struct acpi_hp_softc), }; static devclass_t acpi_hp_devclass; DRIVER_MODULE(acpi_hp, acpi, acpi_hp_driver, acpi_hp_devclass, 0, 0); MODULE_DEPEND(acpi_hp, acpi_wmi, 1, 1, 1); MODULE_DEPEND(acpi_hp, acpi, 1, 1, 1); static void acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc *sc) { int wireless; int new_wlan_status; int new_bluetooth_status; int new_wwan_status; wireless = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); new_wlan_status = -1; new_bluetooth_status = -1; new_wwan_status = -1; if (sc->verbose) device_printf(sc->wmi_dev, "Wireless status is %x\n", wireless); if (sc->wlan_disable_if_radio_off && !(wireless & HP_MASK_WLAN_RADIO) && (wireless & HP_MASK_WLAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x100); new_wlan_status = 0; } else if (sc->wlan_enable_if_radio_on && (wireless & HP_MASK_WLAN_RADIO) && !(wireless & HP_MASK_WLAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x101); new_wlan_status = 1; } if (sc->bluetooth_disable_if_radio_off && !(wireless & HP_MASK_BLUETOOTH_RADIO) && (wireless & HP_MASK_BLUETOOTH_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x200); new_bluetooth_status = 0; } else if (sc->bluetooth_enable_if_radio_on && (wireless & HP_MASK_BLUETOOTH_RADIO) && !(wireless & HP_MASK_BLUETOOTH_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x202); new_bluetooth_status = 1; } if (sc->wwan_disable_if_radio_off && !(wireless & HP_MASK_WWAN_RADIO) && (wireless & HP_MASK_WWAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x400); new_wwan_status = 0; } else if (sc->wwan_enable_if_radio_on && (wireless & HP_MASK_WWAN_RADIO) && !(wireless & HP_MASK_WWAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, 0x404); new_wwan_status = 1; } if (new_wlan_status == -1) { new_wlan_status = (wireless & HP_MASK_WLAN_ON_AIR); if ((new_wlan_status?1:0) != sc->was_wlan_on_air) { sc->was_wlan_on_air = sc->was_wlan_on_air?0:1; if (sc->verbose) device_printf(sc->wmi_dev, "WLAN on air changed to %i " "(new_wlan_status is %i)\n", sc->was_wlan_on_air, new_wlan_status); acpi_UserNotify("HP", sc->handle, 0xc0+sc->was_wlan_on_air); } } if (new_bluetooth_status == -1) { new_bluetooth_status = (wireless & HP_MASK_BLUETOOTH_ON_AIR); if ((new_bluetooth_status?1:0) != sc->was_bluetooth_on_air) { sc->was_bluetooth_on_air = sc->was_bluetooth_on_air? 0:1; if (sc->verbose) device_printf(sc->wmi_dev, "BLUETOOTH on air changed" " to %i (new_bluetooth_status is %i)\n", sc->was_bluetooth_on_air, new_bluetooth_status); acpi_UserNotify("HP", sc->handle, 0xd0+sc->was_bluetooth_on_air); } } if (new_wwan_status == -1) { new_wwan_status = (wireless & HP_MASK_WWAN_ON_AIR); if ((new_wwan_status?1:0) != sc->was_wwan_on_air) { sc->was_wwan_on_air = sc->was_wwan_on_air?0:1; if (sc->verbose) device_printf(sc->wmi_dev, "WWAN on air changed to %i" " (new_wwan_status is %i)\n", sc->was_wwan_on_air, new_wwan_status); acpi_UserNotify("HP", sc->handle, 0xe0+sc->was_wwan_on_air); } } } static int acpi_hp_probe(device_t dev) { if (acpi_disabled("hp") || device_get_unit(dev) != 0) return (ENXIO); device_set_desc(dev, "HP ACPI-WMI Mapping"); return (0); } static int acpi_hp_attach(device_t dev) { struct acpi_hp_softc *sc; struct acpi_softc *acpi_sc; devclass_t wmi_devclass; int arg; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); sc = device_get_softc(dev); sc->dev = dev; sc->handle = acpi_get_handle(dev); sc->has_notify = 0; sc->has_cmi = 0; sc->bluetooth_enable_if_radio_on = 0; sc->bluetooth_disable_if_radio_off = 0; sc->wlan_enable_if_radio_on = 0; sc->wlan_disable_if_radio_off = 0; sc->wlan_enable_if_radio_on = 0; sc->wlan_disable_if_radio_off = 0; sc->was_wlan_on_air = 0; sc->was_bluetooth_on_air = 0; sc->was_wwan_on_air = 0; sc->cmi_detail = 0; sc->cmi_order_size = -1; sc->verbose = 0; memset(sc->cmi_order, 0, sizeof(sc->cmi_order)); acpi_sc = acpi_device_get_parent_softc(dev); if (!(wmi_devclass = devclass_find ("acpi_wmi"))) { device_printf(dev, "Couldn't find acpi_wmi devclass\n"); return (EINVAL); } if (!(sc->wmi_dev = devclass_get_device(wmi_devclass, 0))) { device_printf(dev, "Couldn't find acpi_wmi device\n"); return (EINVAL); } if (!ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_BIOS_GUID)) { device_printf(dev, "WMI device does not provide the HP BIOS GUID\n"); return (EINVAL); } if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_EVENT_GUID)) { device_printf(dev, "HP event GUID detected, installing event handler\n"); if (ACPI_WMI_INSTALL_EVENT_HANDLER(sc->wmi_dev, ACPI_HP_WMI_EVENT_GUID, acpi_hp_notify, dev)) { device_printf(dev, "Could not install notification handler!\n"); } else { sc->has_notify = 1; } } if (ACPI_WMI_PROVIDES_GUID_STRING(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID)) { device_printf(dev, "HP CMI GUID detected\n"); sc->has_cmi = 1; } if (sc->has_cmi) { sc->hpcmi_dev_t = make_dev(&hpcmi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "hpcmi"); sc->hpcmi_dev_t->si_drv1 = sc; sc->hpcmi_open_pid = 0; sc->hpcmi_bufptr = -1; } ACPI_SERIAL_BEGIN(hp); sc->sysctl_ctx = device_get_sysctl_ctx(dev); sc->sysctl_tree = device_get_sysctl_tree(dev); for (int i = 0; acpi_hp_sysctls[i].name != NULL; ++i) { arg = 0; if ((!sc->has_notify && (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON || acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF)) || (arg = acpi_hp_sysctl_get(sc, acpi_hp_sysctls[i].method)) < 0) { continue; } if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WLAN_ON_AIR) { sc->was_wlan_on_air = arg; } else if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_BLUETOOTH_ON_AIR) { sc->was_bluetooth_on_air = arg; } else if (acpi_hp_sysctls[i].method == ACPI_HP_METHOD_WWAN_ON_AIR) { sc->was_wwan_on_air = arg; } SYSCTL_ADD_PROC(sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, acpi_hp_sysctls[i].name, acpi_hp_sysctls[i].access, sc, i, acpi_hp_sysctl, "I", acpi_hp_sysctls[i].description); } ACPI_SERIAL_END(hp); return (0); } static int acpi_hp_detach(device_t dev) { int ret; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); struct acpi_hp_softc *sc = device_get_softc(dev); if (sc->has_cmi && sc->hpcmi_open_pid != 0) { ret = EBUSY; } else { if (sc->has_notify) { ACPI_WMI_REMOVE_EVENT_HANDLER(dev, ACPI_HP_WMI_EVENT_GUID); } if (sc->hpcmi_bufptr != -1) { sbuf_delete(&sc->hpcmi_sbuf); sc->hpcmi_bufptr = -1; } sc->hpcmi_open_pid = 0; destroy_dev(sc->hpcmi_dev_t); ret = 0; } return (ret); } static int acpi_hp_sysctl(SYSCTL_HANDLER_ARGS) { struct acpi_hp_softc *sc; int arg; int oldarg; int error = 0; int function; int method; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = (struct acpi_hp_softc *)oidp->oid_arg1; function = oidp->oid_arg2; method = acpi_hp_sysctls[function].method; ACPI_SERIAL_BEGIN(hp); arg = acpi_hp_sysctl_get(sc, method); oldarg = arg; error = sysctl_handle_int(oidp, &arg, 0, req); if (!error && req->newptr != NULL) { error = acpi_hp_sysctl_set(sc, method, arg, oldarg); } ACPI_SERIAL_END(hp); return (error); } static int acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method) { int val = 0; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_ASSERT(hp); switch (method) { case ACPI_HP_METHOD_WLAN_ENABLED: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WLAN_ENABLED) != 0); break; case ACPI_HP_METHOD_WLAN_RADIO: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WLAN_RADIO) != 0); break; case ACPI_HP_METHOD_WLAN_ON_AIR: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WLAN_ON_AIR) != 0); break; case ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON: val = sc->wlan_enable_if_radio_on; break; case ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF: val = sc->wlan_disable_if_radio_off; break; case ACPI_HP_METHOD_BLUETOOTH_ENABLED: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_BLUETOOTH_ENABLED) != 0); break; case ACPI_HP_METHOD_BLUETOOTH_RADIO: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_BLUETOOTH_RADIO) != 0); break; case ACPI_HP_METHOD_BLUETOOTH_ON_AIR: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_BLUETOOTH_ON_AIR) != 0); break; case ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON: val = sc->bluetooth_enable_if_radio_on; break; case ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF: val = sc->bluetooth_disable_if_radio_off; break; case ACPI_HP_METHOD_WWAN_ENABLED: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WWAN_ENABLED) != 0); break; case ACPI_HP_METHOD_WWAN_RADIO: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WWAN_RADIO) != 0); break; case ACPI_HP_METHOD_WWAN_ON_AIR: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); val = ((val & HP_MASK_WWAN_ON_AIR) != 0); break; case ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON: val = sc->wwan_enable_if_radio_on; break; case ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF: val = sc->wwan_disable_if_radio_off; break; case ACPI_HP_METHOD_ALS: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_ALS_COMMAND, 0, 0); break; case ACPI_HP_METHOD_DISPLAY: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_DISPLAY_COMMAND, 0, 0); break; case ACPI_HP_METHOD_HDDTEMP: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_HDDTEMP_COMMAND, 0, 0); break; case ACPI_HP_METHOD_DOCK: val = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_DOCK_COMMAND, 0, 0); break; case ACPI_HP_METHOD_CMI_DETAIL: val = sc->cmi_detail; break; case ACPI_HP_METHOD_VERBOSE: val = sc->verbose; break; } return (val); } static int acpi_hp_sysctl_set(struct acpi_hp_softc *sc, int method, int arg, int oldarg) { ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_ASSERT(hp); if (method != ACPI_HP_METHOD_CMI_DETAIL && method != ACPI_HP_METHOD_VERBOSE) arg = arg?1:0; if (arg != oldarg) { switch (method) { case ACPI_HP_METHOD_WLAN_ENABLED: return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x101:0x100)); case ACPI_HP_METHOD_WLAN_ENABLE_IF_RADIO_ON: sc->wlan_enable_if_radio_on = arg; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_WLAN_DISABLE_IF_RADIO_OFF: sc->wlan_disable_if_radio_off = arg; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_BLUETOOTH_ENABLED: return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x202:0x200)); case ACPI_HP_METHOD_BLUETOOTH_ENABLE_IF_RADIO_ON: sc->bluetooth_enable_if_radio_on = arg; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_BLUETOOTH_DISABLE_IF_RADIO_OFF: sc->bluetooth_disable_if_radio_off = arg?1:0; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_WWAN_ENABLED: return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 1, arg?0x404:0x400)); case ACPI_HP_METHOD_WWAN_ENABLE_IF_RADIO_ON: sc->wwan_enable_if_radio_on = arg?1:0; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_WWAN_DISABLE_IF_RADIO_OFF: sc->wwan_disable_if_radio_off = arg?1:0; acpi_hp_evaluate_auto_on_off(sc); break; case ACPI_HP_METHOD_ALS: return (acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_ALS_COMMAND, 1, arg?1:0)); case ACPI_HP_METHOD_CMI_DETAIL: sc->cmi_detail = arg; break; case ACPI_HP_METHOD_VERBOSE: sc->verbose = arg; break; } } return (0); } static __inline void acpi_hp_free_buffer(ACPI_BUFFER* buf) { if (buf && buf->Pointer) { AcpiOsFree(buf->Pointer); } } static void acpi_hp_notify(ACPI_HANDLE h, UINT32 notify, void *context) { device_t dev = context; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); struct acpi_hp_softc *sc = device_get_softc(dev); ACPI_BUFFER response = { ACPI_ALLOCATE_BUFFER, NULL }; ACPI_OBJECT *obj; ACPI_WMI_GET_EVENT_DATA(sc->wmi_dev, notify, &response); obj = (ACPI_OBJECT*) response.Pointer; if (obj && obj->Type == ACPI_TYPE_BUFFER && obj->Buffer.Length == 8) { if (*((UINT8 *) obj->Buffer.Pointer) == 0x5) { acpi_hp_evaluate_auto_on_off(sc); } } acpi_hp_free_buffer(&response); } static int acpi_hp_exec_wmi_command(device_t wmi_dev, int command, int is_write, int val) { UINT32 params[5] = { 0x55434553, is_write?2:1, command, is_write?4:0, val}; UINT32* result; ACPI_OBJECT *obj; ACPI_BUFFER in = { sizeof(params), ¶ms }; ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; int retval; if (ACPI_FAILURE(ACPI_WMI_EVALUATE_CALL(wmi_dev, ACPI_HP_WMI_BIOS_GUID, 0, 0x3, &in, &out))) { acpi_hp_free_buffer(&out); return (-EINVAL); } obj = out.Pointer; if (!obj || obj->Type != ACPI_TYPE_BUFFER) { acpi_hp_free_buffer(&out); return (-EINVAL); } result = (UINT32*) obj->Buffer.Pointer; retval = result[2]; if (result[1] > 0) { retval = result[1]; } acpi_hp_free_buffer(&out); return (retval); } static __inline char* acpi_hp_get_string_from_object(ACPI_OBJECT* obj, char* dst, size_t size) { int length; dst[0] = 0; if (obj->Type == ACPI_TYPE_STRING) { length = obj->String.Length+1; if (length > size) { length = size - 1; } strlcpy(dst, obj->String.Pointer, length); acpi_hp_hex_decode(dst); } return (dst); } /* * Read BIOS Setting block in instance "instance". * The block returned is ACPI_TYPE_PACKAGE which should contain the following * elements: * Index Meaning * 0 Setting Name [string] * 1 Value (comma separated, asterisk marks the current value) [string] * 2 Path within the bios hierarchy [string] * 3 IsReadOnly [int] * 4 DisplayInUI [int] * 5 RequiresPhysicalPresence [int] * 6 Sequence for ordering within the bios settings (absolute) [int] * 7 Length of prerequisites array [int] * 8..8+[7] PrerequisiteN [string] * 9+[7] Current value (in case of enum) [string] / Array length [int] * 10+[7] Enum length [int] / Array values * 11+[7]ff Enum value at index x [string] */ static int acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, UINT8 instance, char* outbuf, size_t outsize, UINT32* sequence, int detail) { ACPI_OBJECT *obj; ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; int i; int outlen; int size = 255; int has_enums = 0; int valuebase = 0; char string_buffer[size]; int enumbase; outlen = 0; outbuf[0] = 0; if (ACPI_FAILURE(ACPI_WMI_GET_BLOCK(wmi_dev, guid, instance, &out))) { acpi_hp_free_buffer(&out); return (-EINVAL); } obj = out.Pointer; if (!obj && obj->Type != ACPI_TYPE_PACKAGE) { acpi_hp_free_buffer(&out); return (-EINVAL); } if (obj->Package.Count >= 8 && obj->Package.Elements[7].Type == ACPI_TYPE_INTEGER) { valuebase = 8 + obj->Package.Elements[7].Integer.Value; } /* check if this matches our expectations based on limited knowledge */ if (valuebase > 7 && obj->Package.Count > valuebase + 1 && obj->Package.Elements[0].Type == ACPI_TYPE_STRING && obj->Package.Elements[1].Type == ACPI_TYPE_STRING && obj->Package.Elements[2].Type == ACPI_TYPE_STRING && obj->Package.Elements[3].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[4].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[5].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[6].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[valuebase].Type == ACPI_TYPE_STRING && obj->Package.Elements[valuebase+1].Type == ACPI_TYPE_INTEGER && obj->Package.Count > valuebase + obj->Package.Elements[valuebase+1].Integer.Value ) { enumbase = valuebase + 1; if (detail & ACPI_HP_CMI_DETAIL_PATHS) { strlcat(outbuf, acpi_hp_get_string_from_object( &obj->Package.Elements[2], string_buffer, size), outsize); outlen += 48; while (strlen(outbuf) < outlen) strlcat(outbuf, " ", outsize); } strlcat(outbuf, acpi_hp_get_string_from_object( &obj->Package.Elements[0], string_buffer, size), outsize); outlen += 43; while (strlen(outbuf) < outlen) strlcat(outbuf, " ", outsize); strlcat(outbuf, acpi_hp_get_string_from_object( &obj->Package.Elements[valuebase], string_buffer, size), outsize); outlen += 21; while (strlen(outbuf) < outlen) strlcat(outbuf, " ", outsize); for (i = 0; i < strlen(outbuf); ++i) if (outbuf[i] == '\\') outbuf[i] = '/'; if (detail & ACPI_HP_CMI_DETAIL_ENUMS) { for (i = enumbase + 1; i < enumbase + 1 + obj->Package.Elements[enumbase].Integer.Value; ++i) { acpi_hp_get_string_from_object( &obj->Package.Elements[i], string_buffer, size); if (strlen(string_buffer) > 1 || (strlen(string_buffer) == 1 && string_buffer[0] != ' ')) { if (has_enums) strlcat(outbuf, "/", outsize); else strlcat(outbuf, " (", outsize); strlcat(outbuf, string_buffer, outsize); has_enums = 1; } } } if (has_enums) strlcat(outbuf, ")", outsize); if (detail & ACPI_HP_CMI_DETAIL_FLAGS) { strlcat(outbuf, obj->Package.Elements[3].Integer.Value? " [ReadOnly]":"", outsize); strlcat(outbuf, obj->Package.Elements[4].Integer.Value? "":" [NOUI]", outsize); strlcat(outbuf, obj->Package.Elements[5].Integer.Value? " [RPP]":"", outsize); } *sequence = (UINT32) obj->Package.Elements[6].Integer.Value; } acpi_hp_free_buffer(&out); return (0); } /* * Convert given two digit hex string (hexin) to an UINT8 referenced * by byteout. * Return != 0 if the was a problem (invalid input) */ static __inline int acpi_hp_hex_to_int(const UINT8 *hexin, UINT8 *byteout) { unsigned int hi; unsigned int lo; hi = hexin[0]; lo = hexin[1]; if ('0' <= hi && hi <= '9') hi -= '0'; else if ('A' <= hi && hi <= 'F') hi -= ('A' - 10); else if ('a' <= hi && hi <= 'f') hi -= ('a' - 10); else return (1); if ('0' <= lo && lo <= '9') lo -= '0'; else if ('A' <= lo && lo <= 'F') lo -= ('A' - 10); else if ('a' <= lo && lo <= 'f') lo -= ('a' - 10); else return (1); *byteout = (hi << 4) + lo; return (0); } static void acpi_hp_hex_decode(char* buffer) { int i; int length = strlen(buffer); UINT8 *uin; UINT8 uout; if (((int)length/2)*2 == length || length < 10) return; for (i = 0; i= '0' && buffer[i] <= '9') || (buffer[i] >= 'A' && buffer[i] <= 'F'))) return; } for (i = 0; isi_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(hp); if (sc->hpcmi_open_pid != 0) { ret = EBUSY; } else { if (sbuf_new(&sc->hpcmi_sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) { ret = ENXIO; } else { sc->hpcmi_open_pid = td->td_proc->p_pid; sc->hpcmi_bufptr = 0; ret = 0; } } ACPI_SERIAL_END(hp); return (ret); } /* * close hpcmi device */ static int acpi_hp_hpcmi_close(struct cdev* dev, int flags, int mode, struct thread *td) { struct acpi_hp_softc *sc; int ret; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(hp); if (sc->hpcmi_open_pid == 0) { ret = EBADF; } else { if (sc->hpcmi_bufptr != -1) { sbuf_delete(&sc->hpcmi_sbuf); sc->hpcmi_bufptr = -1; } sc->hpcmi_open_pid = 0; ret = 0; } ACPI_SERIAL_END(hp); return (ret); } /* * Read from hpcmi bios information */ static int acpi_hp_hpcmi_read(struct cdev *dev, struct uio *buf, int flag) { struct acpi_hp_softc *sc; int pos, i, l, ret; UINT8 instance; UINT32 sequence; int linesize = 1025; char line[linesize]; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); sc = dev->si_drv1; ACPI_SERIAL_BEGIN(hp); if (sc->hpcmi_open_pid != buf->uio_td->td_proc->p_pid || sc->hpcmi_bufptr == -1) { ret = EBADF; } else { if (!sbuf_done(&sc->hpcmi_sbuf)) { if (sc->cmi_order_size < 0) { sc->cmi_order_size = 0; for (instance = 0; instance < 128; ++instance) { if (acpi_hp_get_cmi_block(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID, instance, line, linesize, &sequence, sc->cmi_detail)) { instance = 128; } else { pos = sc->cmi_order_size; for (i=0; icmi_order_size && i<127; ++i) { if (sc->cmi_order[i].sequence > sequence) { pos = i; break; } } for (i=sc->cmi_order_size; i>pos; --i) { sc->cmi_order[i].sequence = sc->cmi_order[i-1].sequence; sc->cmi_order[i].instance = sc->cmi_order[i-1].instance; } sc->cmi_order[pos].sequence = sequence; sc->cmi_order[pos].instance = instance; sc->cmi_order_size++; } } } for (i=0; icmi_order_size; ++i) { if (!acpi_hp_get_cmi_block(sc->wmi_dev, ACPI_HP_WMI_CMI_GUID, sc->cmi_order[i].instance, line, linesize, &sequence, sc->cmi_detail)) { sbuf_printf(&sc->hpcmi_sbuf, "%s\n", line); } } sbuf_finish(&sc->hpcmi_sbuf); } if (sbuf_len(&sc->hpcmi_sbuf) <= 0) { sbuf_delete(&sc->hpcmi_sbuf); sc->hpcmi_bufptr = -1; sc->hpcmi_open_pid = 0; ret = ENOMEM; } else { l = min(buf->uio_resid, sbuf_len(&sc->hpcmi_sbuf) - sc->hpcmi_bufptr); ret = (l > 0)?uiomove(sbuf_data(&sc->hpcmi_sbuf) + sc->hpcmi_bufptr, l, buf) : 0; sc->hpcmi_bufptr += l; } } ACPI_SERIAL_END(hp); return (ret); } --------------090600020803080001000309 Content-Type: text/plain; name="acpi_hp.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="acpi_hp.patch" --- share/man/man4/acpi_hp.4.orig 2009-06-26 12:50:30.005708266 +0200 +++ share/man/man4/acpi_hp.4 2009-06-26 13:03:16.331066657 +0200 @@ -166,10 +166,26 @@ .It Li 0x04 Show additional flags of BIOS setting (ReadOnly etc.) .El +.It Va dev.acpi_hp.0.verbose +(read-only) +Set verbosity level .El .Pp Defaults for these sysctls can be set in .Xr sysctl.conf 5 . +.Sh HARDWARE +The +.Nm +driver has been reported to support the following hardware: +.Pp +.Bl -bullet -compact +.It +HP Compaq 8510p +.It +HP Compaq nx7300 +.El +.Pp +It should work on most HP laptops that feature a WMI enabled BIOS. .Sh FILES .Bl -tag -width ".Pa /dev/hpcmi" .It Pa /dev/hpcmi --- sys/dev/acpi_support/acpi_hp.c.orig 2009-06-26 12:43:35.676585431 +0200 +++ sys/dev/acpi_support/acpi_hp.c 2009-06-26 12:54:46.509994426 +0200 @@ -92,6 +92,7 @@ #define ACPI_HP_METHOD_HDDTEMP 18 #define ACPI_HP_METHOD_DOCK 19 #define ACPI_HP_METHOD_CMI_DETAIL 20 +#define ACPI_HP_METHOD_VERBOSE 21 #define HP_MASK_WWAN_ON_AIR 0x1000000 #define HP_MASK_BLUETOOTH_ON_AIR 0x10000 @@ -120,6 +121,7 @@ int has_cmi; /* CMI GUID found */ int cmi_detail; /* CMI detail level (set by sysctl) */ + int verbose; /* add debug output */ int wlan_enable_if_radio_on; /* set by sysctl */ int wlan_disable_if_radio_off; /* set by sysctl */ int bluetooth_enable_if_radio_on; /* set by sysctl */ @@ -274,6 +276,12 @@ "(cat /dev/hpcmi)", .access = CTLTYPE_INT | CTLFLAG_RW }, + { + .name = "verbose", + .method = ACPI_HP_METHOD_VERBOSE, + .description = "Verbosity level", + .access = CTLTYPE_INT | CTLFLAG_RW + }, { NULL, 0, NULL, 0 } }; @@ -333,10 +341,10 @@ static void acpi_hp_evaluate_auto_on_off(struct acpi_hp_softc *sc) { - int wireless; - int new_wlan_status; - int new_bluetooth_status; - int new_wwan_status; + int wireless; + int new_wlan_status; + int new_bluetooth_status; + int new_wwan_status; wireless = acpi_hp_exec_wmi_command(sc->wmi_dev, ACPI_HP_WMI_WIRELESS_COMMAND, 0, 0); @@ -344,7 +352,8 @@ new_bluetooth_status = -1; new_wwan_status = -1; - device_printf(sc->wmi_dev, "Wireless status is %x\n", wireless); + if (sc->verbose) + device_printf(sc->wmi_dev, "Wireless status is %x\n", wireless); if (sc->wlan_disable_if_radio_off && !(wireless & HP_MASK_WLAN_RADIO) && (wireless & HP_MASK_WLAN_ENABLED)) { acpi_hp_exec_wmi_command(sc->wmi_dev, @@ -390,10 +399,11 @@ new_wlan_status = (wireless & HP_MASK_WLAN_ON_AIR); if ((new_wlan_status?1:0) != sc->was_wlan_on_air) { sc->was_wlan_on_air = sc->was_wlan_on_air?0:1; - device_printf(sc->wmi_dev, - "WLAN on air changed to %i " - "(new_wlan_status is %i)\n", - sc->was_wlan_on_air, new_wlan_status); + if (sc->verbose) + device_printf(sc->wmi_dev, + "WLAN on air changed to %i " + "(new_wlan_status is %i)\n", + sc->was_wlan_on_air, new_wlan_status); acpi_UserNotify("HP", sc->handle, 0xc0+sc->was_wlan_on_air); } @@ -403,9 +413,12 @@ if ((new_bluetooth_status?1:0) != sc->was_bluetooth_on_air) { sc->was_bluetooth_on_air = sc->was_bluetooth_on_air? 0:1; - device_printf(sc->wmi_dev, "BLUETOOTH on air changed" - " to %i (new_bluetooth_status is %i)\n", - sc->was_bluetooth_on_air, new_bluetooth_status); + if (sc->verbose) + device_printf(sc->wmi_dev, + "BLUETOOTH on air changed" + " to %i (new_bluetooth_status is %i)\n", + sc->was_bluetooth_on_air, + new_bluetooth_status); acpi_UserNotify("HP", sc->handle, 0xd0+sc->was_bluetooth_on_air); } @@ -414,9 +427,11 @@ new_wwan_status = (wireless & HP_MASK_WWAN_ON_AIR); if ((new_wwan_status?1:0) != sc->was_wwan_on_air) { sc->was_wwan_on_air = sc->was_wwan_on_air?0:1; - device_printf(sc->wmi_dev, "WWAN on air changed to %i" - " (new_wwan_status is %i)\n", - sc->was_wwan_on_air, new_wwan_status); + if (sc->verbose) + device_printf(sc->wmi_dev, + "WWAN on air changed to %i" + " (new_wwan_status is %i)\n", + sc->was_wwan_on_air, new_wwan_status); acpi_UserNotify("HP", sc->handle, 0xe0+sc->was_wwan_on_air); } @@ -439,7 +454,7 @@ struct acpi_hp_softc *sc; struct acpi_softc *acpi_sc; devclass_t wmi_devclass; - int arg; + int arg; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); @@ -459,6 +474,7 @@ sc->was_wwan_on_air = 0; sc->cmi_detail = 0; sc->cmi_order_size = -1; + sc->verbose = 0; memset(sc->cmi_order, 0, sizeof(sc->cmi_order)); acpi_sc = acpi_device_get_parent_softc(dev); @@ -551,7 +567,7 @@ static int acpi_hp_detach(device_t dev) { - int ret; + int ret; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); struct acpi_hp_softc *sc = device_get_softc(dev); @@ -578,12 +594,12 @@ static int acpi_hp_sysctl(SYSCTL_HANDLER_ARGS) { - struct acpi_hp_softc *sc; - int arg; - int oldarg; - int error = 0; - int function; - int method; + struct acpi_hp_softc *sc; + int arg; + int oldarg; + int error = 0; + int function; + int method; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); @@ -606,7 +622,7 @@ static int acpi_hp_sysctl_get(struct acpi_hp_softc *sc, int method) { - int val = 0; + int val = 0; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_ASSERT(hp); @@ -694,6 +710,9 @@ case ACPI_HP_METHOD_CMI_DETAIL: val = sc->cmi_detail; break; + case ACPI_HP_METHOD_VERBOSE: + val = sc->verbose; + break; } return (val); @@ -705,7 +724,8 @@ ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); ACPI_SERIAL_ASSERT(hp); - if (method != ACPI_HP_METHOD_CMI_DETAIL) + if (method != ACPI_HP_METHOD_CMI_DETAIL && + method != ACPI_HP_METHOD_VERBOSE) arg = arg?1:0; if (arg != oldarg) { @@ -753,6 +773,9 @@ case ACPI_HP_METHOD_CMI_DETAIL: sc->cmi_detail = arg; break; + case ACPI_HP_METHOD_VERBOSE: + sc->verbose = arg; + break; } } @@ -788,15 +811,15 @@ static int acpi_hp_exec_wmi_command(device_t wmi_dev, int command, int is_write, int val) { - UINT32 params[5] = { 0x55434553, - is_write?2:1, - command, - is_write?4:0, - val}; - UINT32* result; - ACPI_OBJECT *obj; - ACPI_BUFFER in = { sizeof(params), ¶ms }; - ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; + UINT32 params[5] = { 0x55434553, + is_write?2:1, + command, + is_write?4:0, + val}; + UINT32* result; + ACPI_OBJECT *obj; + ACPI_BUFFER in = { sizeof(params), ¶ms }; + ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; int retval; if (ACPI_FAILURE(ACPI_WMI_EVALUATE_CALL(wmi_dev, ACPI_HP_WMI_BIOS_GUID, @@ -821,7 +844,8 @@ static __inline char* acpi_hp_get_string_from_object(ACPI_OBJECT* obj, char* dst, size_t size) { - int length; + int length; + dst[0] = 0; if (obj->Type == ACPI_TYPE_STRING) { length = obj->String.Length+1; @@ -841,33 +865,32 @@ * The block returned is ACPI_TYPE_PACKAGE which should contain the following * elements: * Index Meaning - * 0 Setting Name [string] - * 1 Value (comma separated, asterisk marks the current value) [string] - * 2 Path within the bios hierarchy [string] - * 3 IsReadOnly [int] - * 4 DisplayInUI [int] - * 5 RequiresPhysicalPresence [int] - * 6 Sequence for ordering within the bios settings (absolute) [int] - * 7 Length of prerequisites array [int] - * 8 Prerequisite1 [string] - * 9 Prerequisite2 [string] - * 10 Prerequisite3 [string] - * 11 Current value (in case of enum) [string] / Array length [int] - * 12 Enum length [int] / Array values - * 13ff Enum value at index x [string] + * 0 Setting Name [string] + * 1 Value (comma separated, asterisk marks the current value) [string] + * 2 Path within the bios hierarchy [string] + * 3 IsReadOnly [int] + * 4 DisplayInUI [int] + * 5 RequiresPhysicalPresence [int] + * 6 Sequence for ordering within the bios settings (absolute) [int] + * 7 Length of prerequisites array [int] + * 8..8+[7] PrerequisiteN [string] + * 9+[7] Current value (in case of enum) [string] / Array length [int] + * 10+[7] Enum length [int] / Array values + * 11+[7]ff Enum value at index x [string] */ static int acpi_hp_get_cmi_block(device_t wmi_dev, const char* guid, UINT8 instance, char* outbuf, size_t outsize, UINT32* sequence, int detail) { - ACPI_OBJECT *obj; - ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; - int i; - int outlen; - int size = 255; - int has_enums = 0; - char string_buffer[size]; - int enumbase; + ACPI_OBJECT *obj; + ACPI_BUFFER out = { ACPI_ALLOCATE_BUFFER, NULL }; + int i; + int outlen; + int size = 255; + int has_enums = 0; + int valuebase = 0; + char string_buffer[size]; + int enumbase; outlen = 0; outbuf[0] = 0; @@ -881,8 +904,13 @@ return (-EINVAL); } + if (obj->Package.Count >= 8 && + obj->Package.Elements[7].Type == ACPI_TYPE_INTEGER) { + valuebase = 8 + obj->Package.Elements[7].Integer.Value; + } + /* check if this matches our expectations based on limited knowledge */ - if (obj->Package.Count >= 13 && + if (valuebase > 7 && obj->Package.Count > valuebase + 1 && obj->Package.Elements[0].Type == ACPI_TYPE_STRING && obj->Package.Elements[1].Type == ACPI_TYPE_STRING && obj->Package.Elements[2].Type == ACPI_TYPE_STRING && @@ -890,20 +918,12 @@ obj->Package.Elements[4].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[5].Type == ACPI_TYPE_INTEGER && obj->Package.Elements[6].Type == ACPI_TYPE_INTEGER && - obj->Package.Elements[7].Type == ACPI_TYPE_INTEGER && - obj->Package.Elements[8].Type == ACPI_TYPE_STRING && - obj->Package.Elements[9].Type == ACPI_TYPE_STRING && - obj->Package.Elements[10].Type == ACPI_TYPE_STRING && - ((obj->Package.Elements[11].Type == ACPI_TYPE_STRING && - obj->Package.Elements[12].Type == ACPI_TYPE_INTEGER && - obj->Package.Count >= - 13+obj->Package.Elements[12].Integer.Value) || - (obj->Package.Elements[11].Type == ACPI_TYPE_INTEGER && - obj->Package.Count >= - 12+obj->Package.Elements[11].Integer.Value)) - ) { - enumbase = obj->Package.Elements[11].Type == ACPI_TYPE_STRING? - 12:11; + obj->Package.Elements[valuebase].Type == ACPI_TYPE_STRING && + obj->Package.Elements[valuebase+1].Type == ACPI_TYPE_INTEGER && + obj->Package.Count > valuebase + + obj->Package.Elements[valuebase+1].Integer.Value + ) { + enumbase = valuebase + 1; if (detail & ACPI_HP_CMI_DETAIL_PATHS) { strlcat(outbuf, acpi_hp_get_string_from_object( &obj->Package.Elements[2], string_buffer, size), @@ -918,11 +938,10 @@ outlen += 43; while (strlen(outbuf) < outlen) strlcat(outbuf, " ", outsize); - if (enumbase == 12) - strlcat(outbuf, acpi_hp_get_string_from_object( - &obj->Package.Elements[11], - string_buffer, size), - outsize); + strlcat(outbuf, acpi_hp_get_string_from_object( + &obj->Package.Elements[valuebase], string_buffer, + size), + outsize); outlen += 21; while (strlen(outbuf) < outlen) strlcat(outbuf, " ", outsize); @@ -930,7 +949,7 @@ if (outbuf[i] == '\\') outbuf[i] = '/'; if (detail & ACPI_HP_CMI_DETAIL_ENUMS) { - for (i = enumbase+1; i < enumbase + 1 + + for (i = enumbase + 1; i < enumbase + 1 + obj->Package.Elements[enumbase].Integer.Value; ++i) { acpi_hp_get_string_from_object( @@ -974,8 +993,8 @@ */ static __inline int acpi_hp_hex_to_int(const UINT8 *hexin, UINT8 *byteout) { - unsigned int hi; - unsigned int lo; + unsigned int hi; + unsigned int lo; hi = hexin[0]; lo = hexin[1]; @@ -1004,10 +1023,10 @@ static void acpi_hp_hex_decode(char* buffer) { - int i; - int length = strlen(buffer); - UINT8 *uin; - UINT8 uout; + int i; + int length = strlen(buffer); + UINT8 *uin; + UINT8 uout; if (((int)length/2)*2 == length || length < 10) return; @@ -1038,8 +1057,8 @@ static int acpi_hp_hpcmi_open(struct cdev* dev, int flags, int mode, struct thread *td) { - struct acpi_hp_softc *sc; - int ret; + struct acpi_hp_softc *sc; + int ret; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); @@ -1070,8 +1089,8 @@ static int acpi_hp_hpcmi_close(struct cdev* dev, int flags, int mode, struct thread *td) { - struct acpi_hp_softc *sc; - int ret; + struct acpi_hp_softc *sc; + int ret; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); @@ -1100,12 +1119,12 @@ static int acpi_hp_hpcmi_read(struct cdev *dev, struct uio *buf, int flag) { - struct acpi_hp_softc *sc; - int pos, i, l, ret; - UINT8 instance; - UINT32 sequence; - int linesize = 1025; - char line[linesize]; + struct acpi_hp_softc *sc; + int pos, i, l, ret; + UINT8 instance; + UINT32 sequence; + int linesize = 1025; + char line[linesize]; if (dev == NULL || dev->si_drv1 == NULL) return (EBADF); --------------090600020803080001000309 Content-Type: application/octet-stream; name="patch.tgz" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="patch.tgz" H4sIADMARkoAA+19+3cauZLw/RX+CsW7NwE3YF5+TzIXA07Y8WsNjicnN4dtQ2P6BtMM3QRn Z/K/b1VJ6lY/aWwy893zhTMTQ3epVFKVSiWpqqQPZmZ/PCvV//b9PuVyea9eZ/C3sr9bwb/4 kX+r5Vq1xiqVarVS24dPjZUrtb39/b+x8nekyf0sbEefAylD44sxsWbGPAZuOTaMSQIef6PY d6D0u3xK/9xiTWv2dW7ejx2WG+RZtVw+ZOfmYKwbE/b2wZiY0yxCNSYTRlA2mxu2Mf9iDEv4 gl5eG0PTdubm3cIxrSnTp0O2sA1mTpltLeYDg57cmVN9/pWNrPmDXWBL0xkza05/rYVDaB6s oTkyBzoiKTB9bjBgyIPpOMaQzebWF3MIX5yx7sA/BiCaTKylOb1nA2s6NLGQTWiw4IPhHNGP SilAnc2skSRrYA0BFGQA2uToQC7i1e+sL/hK9Aphgc/UcsyBUQAQ02YTQIh4vJqpiX6yoNbB RDcfjDn1FKuGSYEqlW6RpEBbhwsg7ztRw3hDJaqhNVg8GFNHl7zbAbZYADBnD7pjzE19Ynvd T3xDzGpDPEnovet0WffytHfbuG4z+H51ffm+02q32MkHeNlmjZveu8tr1rhoseblRe+6c3LT u7zusv/5n0YX4F+9wldc4i4+sPavV9ftbpdBic751VkH8ADi68ZFr9PuFljnonl20+pcvC0w QMMuLnvsrHPe6QFY77KA9RGmcFF2ecrO29fNd/CzcdI56/Q+EEmnnd4F1neKJLKrxnWv07w5 a1yzq5vrq8suR4cta3W6zbNG57zdKjEgA6pm7fftix7rvmucnakthf98DT1pA42NkzOOiyqC hrY61+1mD1vkfWtCvwF5ZwXWvWo3O/il/Wsb2tK4/lAQeLvt/74BIHhJ6FqN88ZbaF5uRc8A V5o31+1zpBi6ontz0u11eje9Nnt7ednqEi6ooNu+ft9ptrvH7OyyS512020XoJZegwgANNBj 8Bq+n9x0O9R3nYte+/r65qrXubzIE6Z3l7fQOUBvA4q3qKMvL6jZ0E+X1x8QMfYJ8aHAbt+1 4fk1div1XAO7ows92OwROgUU6oVO7SntZRftt2edt+2LZhvfXiKm2063nQe2dboI0OFV3zY+ 8GbeUBcgx4A6/lWR4QLxlXVOWaP1voPkC2AQh25HiM7lKaHq3jTfCRZ4I+I/T+eGcdJt/Sd/ 0hqy/1pMDVatFEjXwhOHNZpXnf67K1ZnZu1gL1u6BEXWHbOLxjlIycUD0/k0Dd+HbAuBmfHo zHWbDefmFxinoDwYFJ/oM8ea2VtUuPvh4vKq2+lmexYohoeZOTG4thBlzKlj0UD+bMynxqSQ nU10oXM8pQHan9T4V9CXWQ6IWmZk3i/mXF+MAC9o2pMhK871+3vQEEVrNLINB4oNQatkS02g GaZXE6cB3g4gsD3Mlq5m2cYEFMwUMMHs+xW0mcUmls41lyATGqlnYWJYAPmg+O8sC7Q/aLEC S6A3W/p1TphA9SK5bJcJGicmVKhPgkQKwvpY5vXWh3ZXkAj92Gp3m9cdkuZsD7XmxUNW0CaU os3sxWxmzR3iA7KnCJU6c6AKumNk6M4Cpkx4uQClDF3mcSpLkxlOlTq7PQeuTvU7LHPSuYQx bJTuSwjcBO7pv7GD3Up5Rop9D7/lS9SDQBKoaWDRbDGfWYAJ5gEfm23sVUEplEa+G/MRdF0B Wj0wbNuEKtkXU6dOs7/aA2fCDliBfgLfhvADKpU/Rza9dMZza3E/ZssxmApMn80mYt622QAq GRoOztxTPvODMTG956wCc8tZ4BSc/aLPTQu+8q4gEbWmwAs+d1EPAIMc4KrNW1rq2swjCX60 vyB4toUPDPoOc+fAgGaDsfFVoT8rm+8XFnOKky5RfcRrOAHBcPR7VlyaQ5jmtuzFHXSIYzxs BQSGFZFefQDi3XEYh8mW/vs3dmaSAPDHsrR88+6KnjtfZwbxTVghxDGDN0HMzYSETfUHw4Za jBKBf9EnCxgXxsyYDm0UJASEoWFMSoQXbYLR1yx1CzdtcrZhsDswbJcoLe0JtdJ7b8c0u/w4 KCe3GBqDQNnbs8YFUqKbc8lazuwhSl2Z5YAm8T6vFKysKFhhuVChYTl7Au13QAGM169yWElT OqpeA1p5+5RWGpUVBdXakDeufNMYg18t0prZD9aCBtXcANW4A+93xrPBg4kokL+om9lgMZ8j l/zjhqHYDNG0nbAJrnCyiOcORuXwX2Bq0jiR0Hx48uGfLb3XGVTR52WzONMY9gDMPSyC8lQS c0y32Ttj72FqRYumS2LqDTCOzSaDXBA4+crMh9nEQIPTGB5Ro1EWjkJSKKcP6E4gBlpdEkq6 VC4tJ/q0L5QlzG/396DBSKIGYxNU5ADmE9P5WmIJpef60LSyOezTojWdfM1zkaTHklc5RY1D R431+XCJbbHBCB6M8wnYrWkf+BpGL2QhR3SKBhSCiN1pQHO/gVZAziZVKUD75oi3DWjIdkbI XZK1AvHX66SlCQs6kAS3Bq6EePtx0ljAZI/TVUKVsATAwkqVo1GaOkW5+EoBjRwR7qhdT0Lu nKB8eMM/lZAAgrCIeDieLydQQYSUhJTUhkXF65dkQQn01jOlBWpNJysx1a4jMKhz19Qmywht cptamyyjtcntZrTJMkab3H4/bbJMrU1uN6VNlum1SajOdYTj3LQH6wmHPrGDsqE/3Jk4105o 08w2pjaY/bnGWVyHAoGwVvnq41+LP3Nl4850HnT7cwyG8XDYBztyBksXXEv4ML1rtZj6LhKB afeH1uAztMFHBDyieVrs/UhiKtiVHD6GIMU2OOGUI4uEgPssDhQ2xWaxFs5s4bAc2bJ8rQAs vLyGmkpRhmi5ksIQLVey3bG1ZDMdFYdcSKBdrZpDCnyVw+vuzhmQY4KkzPgKBpdxpI2iS9dF 6SHfbIPV5Gii39vB+ljuGrr6EnqaGc6gJIy8qN6EddodLN18vOlCg/lz0D3CeJMWfMsY6YuJ 4xJqG66pJTqUd5eyopPLYG63vWtct3BzI7igHYOhd2cYaGriepabqXJx6188SS2jLCHuFqDb /PzJBpavgWfTx/1auey2C9dMY2sxGbKlNf+M6u3BAv5462W++StW1BFrZt660w6aoiFhKl3p iiRuESt8j7IduTTGZpO17TOnhRYZs/avjfOrsLnr2ta0TW25C1DR91kYCdZ8CN0sNBb1KBpH 7pIcltPQ+aqliGvhucHbiKPSdF7ZWVhuJG9n8JUgrEx+z2ZggTvApaxYx7of2kfaOvYAvLWu AHh3pbzmKNXytEoEAJwggdrQZ8sc8a0iZjyU2WIGsN+Os38abZX0tA2t5ZRTJ/el2lOXQVHa Prn3xSIqdh55XQnW4zNy10TsWXQK3rdGYCmYjHgAo0oZB6B8cNefXeGwX/FpCVn2fWAkjeag HIYpUIguCCC40oHMiZGGhmgKTie6PWbnxtDUGephGHbrIbjpnlDleEgzmCyGOMLbj7O5Ydus CcqP2RPLSWpCpXZYT9WFcQiwljuYj7tuRWs2wUduMhYPQTZXKtFkxSUJ56EH/dF8WDz453Wc e0IT+xPk1zMlXu+7tdLmQrvNwKi6JD2K8KwudiWp8PLBe+Cf43xbl4XAxqW6ycnnwk63d3n9 wZsK+Va13Fk35zAD6bOZQeKMc+rpI2veXF/j0Qmfb/hBD8w4jSkrTi0w7EwnOLMuYWZdzvEo c0p7kwDqP2Rljd/YCDT9nT38x/3ceCgNDTknurOyObVn5lwsH2ZF7AGOviD2Yd2tFRsmR1Sa hiN2F21irbsXnRtbzmfjq53HeebMnC4eS5FbgYpljLM2TLdQkWPMdDA3j7Jjx5kd7eyMq+Va rQJG/LJaApbC9L/zbga176BexR11eweZ7JUszYYjwgktKI5nJEpEhIsScJX4cUPJmnPbC+d6 nA1xavDBPZiDuWVbI4dqXo6Hgx0+WezMprPZcr4DteD/RRSb0oM9e3QNjh5ulD/o0wXI6ky/ N57IJpCBk5u3XY7O23c3HqGtJh2tToh0ZCRad5ybjkE7cMAAKU54+EMT/zRoNwn+Cv4NGehG aZfRmezcmOBA57IL7MVV0s5JbwdNCTCsQREYA4ctgJsjE9dEIANkQJK9YdHaAfUb1D00RyOD thKlhccl4wz4KHcJvSbauBVI+hXfjebWg6oTsA++QAUIRYfgeOKjWM1SGifmZwPlywYq0QFA rqnmHK9NfgLAFawDZ7WsnNVoZxE3X92+KGX/apeKf6uPVMOD71hHov9PpVzdrYX8f/b3qj/8 f/6Mz852Mcu2V7sAsZ8CSu8NFov0CWLb+GoDHkGAZQMOQYDF9QeC7893BwIk7LneQIBjI85A z6dF+gJxTBtxBeICsCFHIJSyjfgBAaINugEhWRvyAgJUG3QCAmyb8gECVJtxAQJEG/QAAmyb cwDCNm7G/wcw+dx/2PZONvsffOlosJ/AIt0ZgPVll8Zvsv3+6Um31WnltlznoK38cTa7QyOn 5fn0kJfPeh4lgOB5TiVcr1tLW93R5dtQ+tDz36BNq3uwG42hd+IgwRCJb/uBSX8RWEJQFR1l KYMqZO3lDCJJXM5wNRSxauGqjj1r8QI4wmsXP+LAEgZe+lcwYegnLGT8UrZlzZw+vRxvBWRv ps/1B5S9gEjCijn8dGFa4Yeg9gfhp6KFoed3Czv80L5bRNTGnbsioPmiHp4rL0ggzTtaZGBL B/qOeLfDG/4mLTD08QNMV+M3qzZnFIQKIvzzRZ/7KtySGxN9c4QsyP4HX2+xfvPy/OryAjRt hlz9LtvnWfpyftm6OWv30dEvh3uaea+M8Ansg9T0aVLpv73ptDKZrcPd02q9un9YrLf2T4r1 Wq1ePKwd7BcbzWarubffPt2rNLci0eCQlFh2T0/2T8tQttrcqxXru+3D4kn7sFKster1drW5 X95v16OxwHiSSKqtSqV+Uj8sVlunQEqlVi6eHJy2i/VGrVk+bIO5X6ttRTcJpk6Ywz5gz5zD dJApP1Yi4d61Wj2Y7hS4aiRc46zrwgBQLbrSy+YvCqZ6JNAtzL1nMIspgLvhNpzDDHXZ6uMC u9++wJkc6s2E26DCXTdanUuACrdAhbq86Dc61wAWbkO40n7nlKOFYplMuEFqCejyQJHT08xu XJGTs5t27xKmT695e6thZRP3V4O67TxIS4KvsYerS0U2uFKO7aRbPy/jmXmrMLMSz81blZuV eHbexrCzEs/P2zh+VmIZCiMkg3TEclEMSQKK5Z8YjwQUyzgcZwQRyyRUIq12r9E5w/EQyxKw GU/A3kZc1Yo3CBGg0f0l0MOgQvjyOwQXFjoBG8Z4FsIYXatkf/nxYGWlAdjoSn1A0XV6sgla cGWtLrQAjq42gDOs6DxO9a8avXddBCyHh4YC1r64Oedg4aGhgJ2eNd5ysHo2CwvIxcCRDuJ9 c2o7fdv4rT/DQ9Dfs5kbWFLUqhl4tDCmA+M4s7PN5A82XTzccVdxe3F/b0jHRtyCvDMtG40k QnCQQby6LG/d/Qt3ReUztB3vF+YQwfGgMkASGmYDJIVvsvYd/HKc5RM6LCBbZ+3MGMy7iXGs wCzpdAPhwF7OAIDd56eVxxkkgb6LDQ6Gk6qw6ZFitwC0g0OjJRsF5B2heHA+r88MfcCWyaEJ jT6fZFvlPRTCBYGX14dDKH+3uJfuGi6Y4mmougYJdiioA0WifHuSCt3JA9E1K/PKrVuj4vWU umVxXkuJhYChioso7/CJbjvs8xRWHHT4L/iFDPM7D/uweG2NQXXSS4dI8TELk3O7ghwxSngz +wPnsY87UJlt78FxEMgyh+57B9a/HgCskL9ktunwAEdN3+H08NMEcTDHx5ivblhWZHgh/MrL hH2O8B0Vm5nDPg4tKmHNjGkfnvBSM/IC8o5DvJGj4PMGJ2EAtDNH9Jx0w55Z5NMBf23ahPPw RLpDAYqRMZdAvnFNHiN92/xfMTbxG+3vyXd8x0/pjmgd6sJ/rFQPPpGEyq1CUBdZThxzlaHN XVW4IuVLeVe1unrXVZTQXQMmqgcNORjr88w2Ri8IvfdgOGNreCzfcF9ycrYSADwS5Tj7zVO3 3KHp4yf2GlHCf5kSYsxkXrMt1eF5q4CveA34MsFAJ0ilckTFj9535Pk3+d7kbs1TM88Rc8oQ cbN31vtwBebWRY/9gb9wAutf32Yz3wqRBJI+SEMeTf1RxIVc0lPS1IqliQ/zNERxI2gFVbjZ 8xU3inC7KSd3mmgbCN+n7cN4esMaOT2/VWM6nvWc5eYowln12RIQNTmkoT/Kso9qgU9qo5og q3taGzzXohVEh4zOFCPN9Xl6JoVpRlnAFI+iLtq1/zny6zr4pyYufsgFqVPH3VZWTC1sa9ND 0BWANQZg0qI9YRS61szmh2JM9EHqdqw7GpOb8rwhqTrnr9Ikt+vNfOhYn7s573WfN/Mt0858 t4kzXzB84lkzyTL1zHebPPPd/jkzX/RaJD2/0858t99l5otbFqWhf+2ZL64JzxtmirfuCqob Z90UgwugWK4R4Un8rLEmAktWUCi29WJ6UYlCeY7IBiJUVpAkNhGjSAqEszyHJjfoZVUHXTZ/ ieydyPCY51DkbdSsIMnbJoskjFDYGCyxRK9Q2vARS0nFGsj53bqfJWpif2gF2WK7Norm9/5Y lrVoAWLYxc3ZWYGVC/IL+0ZrTyKg277uNM6gw5pnufGsgNEB/NAcT1zP9dkMuEgH7GKlylec fJ05m1t3Rk7u1+EmAwBGwOmOow/GKQCRv2FACfkFNz8kqIFRULpj9PWFgwoelWQuatsRlv2D 6Nr4MjnHA7HFNuR1v3H9tpsE37cNJ7Iitm0PCliAcR4jl/i2AADO7/krazKE74n471Pij0Zi PBoDOkbFM1qYUr3OFNupHIV4q9IIQx4dRQ0OAN3rVeDreb4Hm1P2btm4wPgms8ijUKASbBsP kY1HJ5pSaGef9oAmoCsiyITCtoMx//Nt2luWtNJutLvZUhAQMITvFqMC7fEAFviJ39Qytaq3 7c3byNVJTDPHxiPQgW5tOV4D32hS5HHIN8C8Fnm7YscezGACY7/v8ZID0VMFCk2iECZ8SK4t YuPOFzQgtvS2dwJ7SLgPaC+ZqIb/oG2g0rAPmshGbfyakb7pdsjEKfGGwNNwQ/hrojb0np5y APJvCb7Hh/w1qkKGMx1FjxXUnS/Bdy7SSjfxB+4eVqv9nutJKSikewrMp4ryhQhArnw8SP47 EpSrHw+U/0bQ30F5lr/56CZvG4VlwrGbqN2SyXoK2UygQfAEBdOKVlb5YN8MJrptK90iHwFQ 67oDPBRuEDkBwIlXmiCcgoLlcWBgm0CchR9Fq33Vvmj58aAiKWD0MP6XDKqC+caTmx8otcZG RZfP/s53N6V/vtjsnBpLfgTADQrlqbelH3pFVrV8mnVRKgIb0pr2oPhGaiKhQ5L8HGh2xc4M Egh1FCvicZBC9Z1CongM5I8Y0SHshzzQ4Qo/NG3kIxIWWLJZAg0Y9H9//CcsR9wYB6RPIo3d Y2MvX7IXObePXkactAIl2CEAyGIBxeI5n8fxED87rd3PIGJ0soxtiejsMjz+ls0YE5tCPr2m hpeESP/KdmawkfHd8Z1bWYlpZYW3UjYw+eQO2sn5FdmMwPZe3oVOBv6uDa8q7I0YNFE8Tjr0 pCZlUjc+s6KfvnPTq0lNDzA+drsgmefe9lEyu9VdsDWbm6KpdXUQL1cO4uh9nXjeBhsZzdZn NDElR+vlekwzOTM5N0NjHCcBTk94+MeqI777RtUh0iDWnytH5Tx78ZpRS/yH6byuTMQbFgn/ c/kI6c9EzVJJ85Q8LeXLbDVcX8nu9XeTr8U9wFAH4exm5v/Jd9s8wAhKCyxQlvqHs/nGNuYX fD2DLqQFKs+NbRcvxuprUT2GaL654zF6xPrZGDGik3VNFEODSEJcDTo3BFgbfM3iS/7s9sHT mc355zYpwG31AIYzProj/ez2sTpItAcRhWlt5g895oc6NiwBvhEeGMPLlWP4Nm4MLxPG8DJ2 DC8jx/ByI2NYjN/bmPEbGL7hzklgqEKhGLvLp49dQxm7y4ix+03d2cr6lpP+fShakEA/EYjM m5SDJe1Wnv3xh1zH4qbGYmo6WJbYVMbOnBu4tc5y7YtfYTryfNxsgMa9vhy34OO23tzyOGFG Exy1xYYUR62vMrC+Ova/Es/59wEnUCw9M9IPT6w7uXtNRp/fI2U0AZ7eXDQxXKmP0UbtHO2X sO18bgGgMwcWyXnW748W00G/T82xByCPSodR7Tm+2UfSC185hPgt/JbEeg2L8CdqGc89UFgQ 8iFulnhPEg3FKLBI88oDjFtcBCD+HCyhiVt9E6H3fQWXUQW9XffAQ8+3Si5jFQUiYB+MB9os VYvQSlnugKgv8vljsVlC4sGHmScjMx2dw3yiwscjmHWKfHKx4aI7MqdDlnMDS7bywsDzKzY+ 9JqYOmn6ymFUyE2SIXGBniKV4Q7kzsX7xlnes8ZfqApSJeKehjhW6KMTdwueRA6AriaGRiXa pCJwlEeu9DEK8OJtQJUHzVg30CWWvKxU/uQqyzN+WIZNyQTUbMGgzsj7DZGtpPk5JHshPitp Bpp4rmDyBcZUywMHE//RdvJkgkdW/L3YcZV0+0jsXHR7jbMzUa84OFi1PPCI9Hbj5G45yrOY vCNJ57STUFAvC2r9LtCC4heSZOhYvoRyjQKfiqz4jZf0/R8Z0JQgyyKM0Nfhkka/jlYXRMob jpoeeN6tAP6gf8Y92y+5l+pmNykYJP0azE23897Cg9t37TYef+3V6wW5F+1R4aEuvrHh2/xL hawmP4B0eRUaTnnDXVmlMvwm50ZxvnbSftu5yI1nYv6DKlwf38Bc6D5XJzfF4zcSHF9IeIyq zNGBDhEZ8go1P9HRJBoneB54zDRNdDHM6bJdZHq+CAgNLaNpsyACJ9/fBqMXuzydYyHYTQLh U/BFuTs8GWOS59UGkG6U1hhnlefhi6Iwn/dw5rhwRJ1VDgqr6gVEP8GExzURHgqa04UhdZRr VMdQnOBhm7hpQRaqogZX1SNVxQoXw9Wr6Q1VrK4GkxZ2bnXwjzjLbrRaqMebOb+mKXgQzXed s9Z1+yIX0C75ArsEVdm46ZFrWSZGeRSieM09EgqcUphSg0CgdDtbcVgVlwdhFajqE4+bhPJc vRaK8iKQx0lQGrA/ad0SuZbCs6qExUxgJsMjh4i5hJaJxGIgD7C1T266H5Q90N+zGR8mro6F ULgT93X7/PJ9O2CUqAZEjMmkjsPQdPbC28PIYBAIdO4E5vDcSw8SH/NledxkSOjj51BgvTO3 vtJUHpiKpc3obgp7/Ie/sRKQ4NmxYlGsLG7Fd+6x4f405nNLLpD4ExQQJRwj40VspBaz8Oo4 5mA0b5nDWfEN/NsHorBvZe1QxveuSusvrmFCg1UWkkroON5aySTpfc8TRXSTq45kNwl4bpv2 ocE5pLLAXpJHDFhqc+M3OVBe8EIwRuBh8c3UWAoJRDOFy6BEG+WS45JT4O42rqtNCmVCeFeI U3rHHKlsvuhi1fwUQfCR3OjCl55rP/Lk5DlRHYUN6XZifP0RdB4nJ+3xxoojHHneLbDmMCt1 3OkoV3AIfDc39M/HCeSS7fGXECuOitKTyqfmv4RWaRWkJzZsLnqEJ2xApcIdZTpGYI+M9lyB P3Tq+md3d/jYN12nB06W/zqy1xHroKn711G9loAnrd38cpgYGp26ltXyviKUetWguv0L9fbt +nr79i/T27fr6u3bv05v366tt6OX+QHNGhN6nwZ3Cr0dG6W/An/jrPvMDlZyEil9m1SniNV4 Zr2B3Eop6xZBGc+sO5CvKW27L5u/PLfRSm6nlLV6URZ+kVHyaazAIAIe/MVlLg2lrLro417p iVZ6avf8SMd8NN03aqvjwkasw14khKq4flixsKK78u4+LfyLzgCyEnwIpUQ7+JZ5eJ2QaqHg dndqYUrlDOUCIuXk3njEXTlJ2NY0XVccm4pNsRXhIgO+byElbX0Td+XR7OboiDSF/xxOVcvV I+6VGcupVTZYmrP379FXiYxbecjvDrHNSNLtXzHM6uX6EXe2jB9m8ZZGJsn38rt0UPJQi3V4 3TQtwoLZAI98lkyAPejMFcsW/xQbdseQ4yWxHcosG/DQCBX/5p9r/Rvs/b45pRuiMajDnXMx s3mfB0bxE+STm9PT9jUFS9F8gzMT5g56+RIfFd9c8eQ+fC5qAJZLG9P45nwvj/2OWb4anxB9 hnO6ehgAbRevjiMn+/5NrZo04RdEPXwvbv1DAaWjMPf7zJoSP37nrGucnV02G722gOBBm+yb LHd58l/tZo9tW3f/ko9QyN62e2JPH7NL+8/rZa+8lJXRfu3dv3CVouDczrvUlAQnxMYswgID 4U/xTe/rzHAP5SjsVLREApyQNJTOjOm9M0bIg7x7gLGdy/HoPahLBXalAsDLj7vivCHNIOYO DFHiqLY22mBcM1QyJkgSpUtk2MtQpmD74y4FrWFLduu1+u5uzT2CkcV/rh5V3IdKLKYfCBS3 +xCqQhkQgYyol/AWEr9UZFSp4GzJmFOiRXhccQLzIAv8mydXAtxaOGlEERsPegKIomMO14Hk FJTVzXXb8yZpv2+c3SCKJiDLuf0a6XAkj5Fx/fFYAxrNKfwDFOUDnvk+NuN7cUpEaqvocy3i Yg4wAZF+gS/++EOR6RdhmX5yrZw5OL4EvyLF/Zh0LV/78BIfq58EfeJ35RN7o5wN+mArn47j hZ/T5zstC66dXI1O4a3uqCB15czN6X0f76Tp80yPPkWBjZFxt0PbcYNu8Q/X+lMnMyEFgDQA yMfyJ3lmxvVJlCLhvka8sROhPni/dYkeoVM0OlJEPALojVexUpBcE4vMO3905pPB7GuOCFax Cm4UGC9KbI0IAoZy+cBqlD+CJyL7/LV77WFXXGNJsc2YZcBNlLklv21RLne8BZEDcaR4T5at 9MlVo/lL421bJHUXNzzi7CWv2HAvpkBshkj5fsTTxA+NR3Zu6FPxtszER1J3gW5AHzmzP9EN HxLiPV4xirfugmZitoHKgtzkdBtvsrA/swd9/tkmAmTaPrqVNO9DV5XorvByUbzyQhBNmUXH pjHX54PxV1+ZmizTsd0rQD8Cg+hlXb4UyTc605uO93ZXvr02fluYMEquxl9tc6BPrvCGFex8 F3TP6wqRjw+9psgPFTsmSKqbij+n39nWZOFgQyWufYlLTHnWiM3mxhxpsEGL40VLc11pxEGp dKB93P/ErhSoC18nHNJ7+DTVzkWvLkY2HlRhTBcPXm+zHdagWoT4u5VVygJVG+B9b90i/DpZ Aq4gMBjTBMzr1PkNdI/sUaVwJ2o+XTugPxjKn6XZMCmcPzmQ3928iZ8O089voGLkFyg0Mdzz feHzXN3dlU/QJwP5IWPXeFZY7L473XWGpvSNGaFZuZr+iKg+yQKIAeFRZfIaRUneF1KFJk63 aAaeQKN+8aZa3tNeuoTvOaH6jETfhCr02FOrVeaNK33wWb83Sk1rAZx/A/alu3fme98WuhAk uhSea/CWlbdihhfmlcutA6bFo8J7bu9hDicNKWjD5KVjAxX9iF8kRHerYh7QxZxushvwLDg2 wxro1pGJ+WBiPlDMFDsxhvc8KSs20qPkDagW2aOBViv0aqC1kzugHNUBfLJdUbLy5JLVJ5es JbBrRdH604vuPr3o3tOLulx8cm+5GLRIXiWSESVLHCxlfb6xQCWFl47QZDCWfHIq7Taxg/Ey Nk+6dDhDk013cnIyWGGi0s7Kyzh5LDCf7uVTS55vx4jphW8LCd2rvWb1A3oAttfEII8seC6I QYdWDsiD5YKkbrGtAlPRuiboZtpTTt0epTk1/J2iNSsbs8GGeEMg1CDesataVa1sqlXccZ47 zZtQ1o+M+8lnRbSkmJPNTzjeXv3zn6/ykkT5mL3aeZVG4CnjvxB4lwJ3BOGoIWLUJ0yTuwLR fSphw7MVL+U6/GcyaTiHRWK4Z4a45pbwBhT3LOWd6QPOg/KpcBdz4WQeDQVdzOc4idpnRIFd BKbGK/ZKhtDwCl2jjHMmgv87Af5nuL92HDjLheGDQAEJDkCrdiIPvCW1QP9ID1w/2SEi8gEa VkkXXRQRo05j51+f1Lgx4Fvso1yRfdo62gp2Rjrs9VjsgJJ9vLi86Xx6GubdJLqvriJIxi7f dhOyu5s1+fh5Pmz8pdt9EVvpcp+gaU2/GHOH3Zt4w6+ztNjQvDcdNoZlFpcgkAPj0ZzmMZha n4p10tyg24UHBt0Rd/cV/nMMtMT53gNVhZ4l3AzlFzLrGJF3B03AxSPoWhPv4Z4Beeoizt0J ohNxZevDschlly/cxM4tESaXbtuCBFp6Laa2eU87GLCcGePqyfdkYmGXjFG9EQ4YuAAysdzf Fbn59ar8iv0ET8lfHv6F768OScPCjyL8KKNmdWMrXjXC4KcKOAEUYSmc95XSw6VGvlK6v5Sy Nqnk/ZRCIwAJ/OtRCj9iKfWBnyrgiZT6So18pVZQKrmEMo4t/YnV8zCPcIYEZTTq0CUuF550 dJYrZW/zjetxN2WeuEJme2FO3R8LoEg6L+QwYC3Pi+9U89tV1PkC2x9/yG8/YRvFRhmW9E3Y P4kNR29243G5OVOr5P9ek5ODOJDCicN0Jw5SxRKvF7kj4QGJV+QNcVUcaIlngu1etBSfzfyF GhGFgPl5X+3wja8po9tmosVT401Z0Nb+SxchUr7gXC4H9zDFQF7QjvpCLrVl0Z0a2ivE2jzj bME+EK/FNiv0Iocrq1uelDhQTUgYtznkhX5I7xwM19xm7jHLaKLf28JBBwStIPMZOmNKLrjt DNPFblCET1ZMjF9QjmhXh6doUEI7RViBMlbaJ43WKY+45Kd3LnRSfIQ/bGb9mB4Mqpkay2BE jUzWWi8f7hVY9+TmlIKy2r/22hetvBCz12pshKwIc0yQFLNA9G8w+MYZFt84Q8x1AW9ndJGL H9aN4uGH6l4cjjh2WxFU4UbocFHhSSTTywrB//8hLK9DwgLIo4TlrwjPUsOv1mQ5HYjgekKw nTbTzSle0U0bYskCgKxU+c+2if/iycK0wPzAgSIFIh3LZ5ZNsYkTjD1y3Nko491v5p3nenem ydJoJokN4Eq5uuvu69KLj/Ltp+8gVJmnqCByq4Ce6ofHOt/pAaLCYuEJVbI4vuAiZ03DAqfM thEZQ7xg4Oh8IlzfyEh2cXLGp0L5C2yBKt+ekUta8ca3CIw+mgi57Pi9YWVOA2XXXEAhf0Fy BJdhKnWPIeSi0eej4y1IM0orXLr54k9N0sDFU/GkVW6wEu95n7wuy98MrIOIPgRLw/ypUt33 wPzr/hBjMAbXXQu9cc9XvBZI0sxj9wH3HGLil3wsWuX+FRTHN4l8Ht4AdvVBsWh6dcdT+lop EoAqVjy44zhEHl+SESnKwdc4Pyi0IY62REKoXCQpwXrDvahpPmlyNxQ8SYmUkOOgNLxIOVaQ qsjR4m3PxHUyHzrKAPK2l7zzvLghRLpGJBYJ2Upbf7cp0y1izgd2VnjJkTk17XHkxOgGPyMc LluCQGiql589yyZMsa7pdnnePg/abujy8WBOc64un0PnDQssntxiVuGESkteqSw3IdeSnwHj g/XF4K0f6o4exqfF4aNZlECORENCrYf1ymRti/Fv/w4fMV5KMzzs+051lMuYrYbB38r+bgX/ 4kf+rVWqu3usUqlWK7V9+NRYuVLfq1f/xsrfiR7fZwGjeg6kDPFSCrz5MQZuOTaMSQIef6PY d6D0u3yKxSKzwfgzdh70Kf5f35EiUS9Zc/M+Uy2XD4vlvWIVmFQ92i0f1cqlcnl3v3xQ3dtj WhnvDNY0LRaLD0HtqFw7quyVarVKeW9vb3dfIPjHP0C/7O0VKmWm4V+A/cc/sqzUcdiZyeiG YNYdW0u8mZbu09QnfPmEXiT8dkrhDpRzHW4MZ1DKA472JKshovc6GqMlSVi5JLyIs1oOjfSi BYXyWa0LiuWL/64SjoSVrmZZ1jJG+mLi2ORr44wNUHAiIQEb6FN2Z9C9ryasCkq/zsWr0sCa jtguKwEh3TF717hu3Tau21mtN4baSxcPWU0k3h/rNqAwpmDVz6y5wxNR2osZ/vB7SgHofLiE Lj8CDECYVjqZsOLdYgJKnRUH1sNMHzjU8KyGyavwwW/sYLdSnoWeTh/3a8hF3lWIDLpLuGkt rflnPOt/sGwHk6FN9JljzdBrSocFi0F39DCdYRo1eQcW8qME7YemnnbO2l34irQ5+j0rLs2h M2ZbpStduQZii3Pa9yxLkvnVpic8ox7vBleyBlHyWa8d1XZLe/t7uwe79VpFlc9EXEExrx/V 90q75cPDw3q9uqdI6WG1AD/h332S0FSXpMdBKbekx4EEr0nXUt2Tzjx8EaGbGfWm9BBg/FXp NEirZWx/pVoRHZDqlmqW8ppq5tqMEfdUaykvqmZPuKlaLZP+Qmf21LuqsSer+3Xsyeo+aL0q 78pM/L1NLN1lSQxvS9Iyv8P/kXc3aakub9LS3N6kpaNIQ4pAHqNvcEI/NeyMWq1Gur9Wr+Bf 7A3f9RteROh692+A8VkkP2/vBg7+O3QFh/c4fAeHUkS9hEML3O2hRV/u4T0OY1aKqJixv9a+ 4IOtccMH9Xm9DmNYq+1WCwdc/hLu92AxF3ww6Jxn3+ehhXM3axu4JoRt6J4Qtt5FISxt9n1i wmGZC/7hYaFSEWrgKcny2dOy5bPM2unyi5nEtNpFqcWS0uK7QEkp8YvKgi1FOnwtE5EDHB8m Uatl0mby90Mm0e2DTEk88mF1QnCWWZnNn+EqFSWrXq4VDplWr9S8+eV56fdVWVkr/75L9mrx SUqy7wpN2iT7QQEKJdmPS67/ZFFadU+AB5O2DW6J2EZ4IDGtWVe2ki8L8ASsUicBq+4HNNea VwT4NFf6OwJ8mivdJQGrRC/hIgBP9pIuAQhprORLAJ4pZgnk+pVVIs0hAVtB9LrSFHt3gSdI tUM0ROq7dbmmiD//YokZ/1lCyn9uxFG8sKZmSERb6wmJNBknffcQjfj6vkd6pEiWj8WrYCp6 Fn12hKaVFk5Gz9bPRs/WS0fPm7W7i8s7bXdvXzRLOd4MXCwYyFDqGtx0LKl56UpZ5on9/ITg ZGrC/gHOe9ruYV3Of1GNSEqySW2Jq10IFJch3mSZZJO/UHJs8gdeik3+W2at1BLE3Sep8oes R/5WapKPvLrkE1nbOnwIifteeQ/lYq9aTZCLtRNNujLjpprU/Jkn1xiiPsmJS2hDTTmk5fd+ pQyTGI3cVdkLWFyGIOamH9CSsxdokUmCNLc4rN6prf5EQUjtfnkXO36/WpdrtU32By7iUqb4 yYvFWspsQFrKdEAslA+IieVbKCMQdcdujZi3X5PMS8O9mOQT+Mbl30oGRuWf0DIKC5GHxEci 9AC00C7TDioV/Bs3ZDYUxE8DSWSRiI/il0ZKII7ffexG8ocBKZbffcyj+WWN20xG8xcjkjwU fQkjVsfz++HTBTxqKVIYSMPI33b51G16CIxaLp/yhmvhPAZaROSmtmYmA+0JoZ7Ml8uAVPym shmgFB/Qbq92UJfax5XiQPj9qhiadeLv+ZQgA/A1Xzi+hpaeEpDP0kXks5Uh+dTaeqVQq0Fz 93YLNW45bDjG3R/kHopyL7ph7tEx7kU3yH0DEe5FN8Q9bXx70Q1wD0W3F93w9nBse9ENbl8R 2V50Q9ufG9dedAPb00S1I/QB7wkFpuJv+GEIoBpgTDkIUAsAEOueFxNPeIhrKyPiCbQ2GrFV 8fDa6uQK2oazK2hPSa+gJeZX0JITLGhrZFjQNpliQVs3x4KWIsmCtrksC9paaRa0dfIs0ElZ lNWzmVQLz8q1QPPMKmsl3RzM5yvTXQyKdAv8l5pugT8JpFsokgtuIChQeOHyAl5mhdVWRlp7 SWaI0PwpIrRwjggtMkmEPJL1Z4nQktJEaME8EWjoq5kiWChVBE3KBxWwPbTDMqzma8LkDydZ 4Ia3tirPgvaMRAvaszItaEAgGi+bSrZQTGgq9BO19Rn5GNjTEzIkFV2RkSGp6IqUDCQqh+VC tQyyUjlwTz7iEa5Kt5BUdlW+haSyqxIuFJ8oo6vKHiR3YFLRw6cXrayQFl42l4spvUJgEmuO lJjkzpJDSLzLVGpaPHLfCKfoOdGYddqyJj3VOHqC+SzyeVGGr6jUpBbrd/XPtPSH2o8qtD0d 3+kpU4KkQrEyJ0gElsikINrTs4JoMi2IlpQXhK2RGIS2o9ZMQEEOQmunBiGnNVSFFVCJtQPp XhPMqcFWp5+IojmQf6LIu8DrI4wUyZPcrNvaohs+ENNkENWCAhXdev7eI1BbnxAtoduTEn9Q OUGG5qeCBXN/bKb3idW1Mu7VHNYP5YlUbK4PJojyJ/tIIcVuto9iJiLdhxad7EOLgo1NDSLP D9fMDSKLibAQauEq/lKv7dfJvDysiR0uddGyicwC1FlqJgE2pqWC7xHGsmvhDARaOAUBGs2B JAQsmIWA3DXLaDCjU3W5WovwrMv62hMZHe9uxblLm9gAeb4VDM2mCHn5i8diazLGXt3Ji8Ch +aLsNV+YvTwTeEqgPRP9ARrwALtjd19wOmplupE47zTHh/KYdPUJID9EFR2QKiKThUMyeRfs l3kXHByu7ILnhi//v9oHMC7odLhSqRwmHQ8/NYY3VbuDQbxywHjhcu5pjhd5J4ZgMIJX7B8E A3jT9GqQDC0imFiLiiaWCELEaHHxxM/l3V8dLfPj8+Pz4/Pj8+Pz4/Pj8+Pz4/Pj8+Pz4/Pj 8+Pz7/n5P7EUM4QA8AAA --------------090600020803080001000309-- From owner-freebsd-acpi@FreeBSD.ORG Sat Jun 27 12:42:31 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 41E3E1065672 for ; Sat, 27 Jun 2009 12:42:31 +0000 (UTC) (envelope-from patttern@gmail.com) Received: from mail-fx0-f218.google.com (mail-fx0-f218.google.com [209.85.220.218]) by mx1.freebsd.org (Postfix) with ESMTP id C71588FC17 for ; Sat, 27 Jun 2009 12:42:30 +0000 (UTC) (envelope-from patttern@gmail.com) Received: by fxm18 with SMTP id 18so1161818fxm.43 for ; Sat, 27 Jun 2009 05:42:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:date:message-id:subject :from:to:content-type; bh=amwhHfJUVG89Wuw1Eb8P0+2vffXr/kZ3uEYxjqR8W48=; b=dQrRAW30B2nwVBB4avtHBgrShLnMTqazi4ui7uGac5tV2B7tQbaq55eEs8oD3u2KvZ 4wU6WxhXU22TWQrOgvXOBu0+V7eBSsUKQ2pCnQFQ/qqZ5CXv7+B9Nr5hRB3YoLRB8sjN 69J3ydn/a/GJWUanGP6YO3T5fipQo7TR1DMDw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=pL2BrTzanG/RqWWiTkm6cwMORhdxZ5DJZkMcUs+n6mVBFM4jmnS8eWTQFbMuCHIbFu O8czx2U/dWE3pKvMJJaTm62PHYIBGzeKBpEmjBSqCpaKkLxPxmkNAKyuJDIn06b5yrh5 Jnghys5qD+dVtk4wJjPZadApFdp6yUh+Ygvms= MIME-Version: 1.0 Received: by 10.204.70.135 with SMTP id d7mr4715371bkj.194.1246106549386; Sat, 27 Jun 2009 05:42:29 -0700 (PDT) Date: Sat, 27 Jun 2009 16:42:29 +0400 Message-ID: <107cc88f0906270542n572b6e90y88e59db2695e920@mail.gmail.com> From: Pattern To: freebsd-acpi@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Re: i386/136008: [acpi] Dell Vostro 1310 will not shutdown X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Jun 2009 12:42:31 -0000 Try to replace this strings in dburkland-DellVostro1310.asl DefinitionBlock ("/tmp/acpidump.aml", "DSDT", 2, "TOSCPL", "CRESTLNE", 0x06040000) { External (_PSS, IntObj) External (^CPU0._PPC) with new DefinitionBlock ("dburkland-DellVostro1310.aml", "DSDT", 2, "TOSCPL", "CRESTLNE", 0x06040000) { External (_PSS, IntObj) External (\_PR.CPU0._PPC) After this change i've got a working aml dburkland-DellVostro1310.aml. Use it for acpi_dsdt. http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/acpi-debug.html #11.16.5.3 Overriding the Default AML Here is the output from "iasl dburkland-DellVostro1310.asl > iasl.log" > > http://jperzel.net/vostro1310/current/iasl.log > > http://jperzel.net/vostro1310/current/iasl.core > > Thanks again. > > Dan > > From owner-freebsd-acpi@FreeBSD.ORG Sat Jun 27 16:05:28 2009 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EE8CE1065670 for ; Sat, 27 Jun 2009 16:05:28 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: from mail.bindone.de (mail.bindone.de [80.190.134.51]) by mx1.freebsd.org (Postfix) with SMTP id 68FE08FC18 for ; Sat, 27 Jun 2009 16:05:28 +0000 (UTC) (envelope-from freebsdusb@bindone.de) Received: (qmail 61604 invoked by uid 89); 27 Jun 2009 16:05:27 -0000 Received: from unknown (HELO ufo.bindone.de) (mg@bindone.de@87.152.167.4) by mail.bindone.de with ESMTPA; 27 Jun 2009 16:05:27 -0000 Message-ID: <4A464343.8090502@bindone.de> Date: Sat, 27 Jun 2009 18:05:23 +0200 From: Michael Gmelin User-Agent: Thunderbird 2.0.0.17pre (X11/20090202) MIME-Version: 1.0 To: "Paul B. Mahol" References: <4A3E1784.2050406@bindone.de> <3a142e750906232257y4b1e255en9374c05079f04520@mail.gmail.com> <4A41C2CF.4020205@bindone.de> <3a142e750906232353g37b5f001p89948a2fe6a3e66e@mail.gmail.com> <4A41E39E.1090208@bindone.de> <4A41E66D.2080504@bindone.de> <3a142e750906240347o393ea738i54fc9ce215bebab2@mail.gmail.com> <4A44AC9B.504@bindone.de> <3a142e750906270327t765077f8ta4dffed054f70c53@mail.gmail.com> <4A45FF8C.1070604@bindone.de> <3a142e750906270839x41686881j13c7a73ae38586e4@mail.gmail.com> In-Reply-To: <3a142e750906270839x41686881j13c7a73ae38586e4@mail.gmail.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: freebsd-acpi@freebsd.org Subject: Re: Two new acpi modules, acpi_wmi and acpi_hp X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Jun 2009 16:05:29 -0000 Paul B. Mahol wrote: > On 6/27/09, Michael wrote: >> Paul B. Mahol wrote: >>> On 6/26/09, Michael wrote: >>>> Paul B. Mahol wrote: >>>>> On 6/24/09, Michael wrote: >>>>>> Besides the other information requested, maybe you can also tell me >>>>>> your >>>>>> exact HP model number >>>>> Here is information you requested. >>>>> >>>> Hi Paul, >>>> >>>> please find attached a patch against the current version of the acpi_hp >>>> driver in CURRENT (source and manpage). It might need some tweaking if >>>> you're testing on 7.2 (headers). I also provided the full acpi_hp.c and >>>> acpi_hp.4 versions in case you can't patch. >>>> >>>> Patch: >>>> patch -d /usr/src < /path/to/acpi_hp.patch >>>> >>>> This patch adds the sysctl dev.acpi_hp.0.verbose (as you suggested) and >>>> should fix /dev/hpcmi on your machine. >>>> >>>> Please tell me if this works, so I can send it to Raul. >>> It works. >>> But I still get acpica error: >>> >>> ACPI Error: Field [C2CA] at 336 exceeds Buffer [C281] size 328 (bits) >>> 20090521 dsopcode-697 >>> ACPI Error (psparse-0633): Method parse/execution failed >>> [\\_SB_.C241.WQBC] (Node 0xc3dcfb60), AE_AML_BUFFER_LIMIT >>> >> This is a bug in the DSDT provided by HP. The error is emitted in the >> underlying acpi layers while reading a buffer that contains more data >> then it should. The only thing you could do about this is patching your >> DSDT. > > How, what to modify? > I already modified and use custom DSTD, because one of thermal sensors > reported absurd temperature most of time ... > > Search for the field C281. Modify C281 to say 336 bits instead of 328. (this should be line 7498 in your DSDT: Name (C281, Buffer (0x29) {}) should be changed to Name (C281, Buffer (0x2A) {}) ) That's the theory, I can't tell if that has any negative side effects. It seems like that's the last BIOS entry instance in the DSDT (same here, my machine provides 57, yours 41 if I recall correctly). So changing this is absolutely your own risk + I don't think it make sense to require all users to change their DSDT anyway. If I had more evidence that this is happening with all HPs I could change the acpi_wmi kernel interface to allow querying the number of instances of the GUID and iterate only over numberofinstances-1 instances to avoid this error. What do you think of the following plan: - Extend acpi_emi to provide a method to query the number of instances of a GUID. This way acpi_hp could know the number of instances and avoid hitting the last instance - Make acpi_hp only iterate over maxinstances-1 instances - Extend cmi_detail to have an additional bit that disables this behaviour (so it behaves like it did before, assuming that there are HP notebooks that don't have these issues) - Document all of this in the man page cheers Michael