Dell acpi_video patch
John Baldwin
jhb at freebsd.org
Fri Oct 12 15:54:55 UTC 2012
On Friday, October 05, 2012 5:53:16 pm Juergen Lock wrote:
> Hi!
>
> I finally took a closer look why acpi_video found nothing on my
> Dell laptop (Precision M4500), and came up with this patch:
>
> --- sys/dev/acpica/acpi_video.c.orig
> +++ sys/dev/acpica/acpi_video.c
> @@ -906,7 +906,7 @@ vid_enum_outputs_subr(ACPI_HANDLE handle
>
> for (i = 0; i < argset->dod_pkg->Package.Count; i++) {
> if (acpi_PkgInt32(argset->dod_pkg, i, &val) == 0 &&
> - (val & DOD_DEVID_MASK_FULL) == adr) {
> + (val & (DOD_DEVID_MASK_FULL | 0x80000000)) == adr) {
> argset->callback(handle, val, argset->context);
> argset->count++;
> }
>
> which gives me:
I think this is correct, but in we need to do more to properly handle that
flag (DOD_DEVID_SCHEME_STD). Specifically, we shouldn't trust any bits in the
device ID unless that bit is set (except for the special case of
DOD_DEVID_LCD) as per my reading of the _DOD description in the ACPI 3.0b
spec. I think this larger patch will do that while also fixing your case:
Index: acpi_video.c
===================================================================
--- acpi_video.c (revision 241382)
+++ acpi_video.c (working copy)
@@ -320,7 +320,8 @@ acpi_video_resume(device_t dev)
ACPI_SERIAL_BEGIN(video_output);
STAILQ_FOREACH_SAFE(vo, &sc->vid_outputs, vo_next, vn) {
if ((vo->adr & DOD_DEVID_MASK_FULL) != DOD_DEVID_LCD &&
- (vo->adr & DOD_DEVID_MASK) != DOD_DEVID_INTDFP)
+ (vo->adr & (DOD_DEVID_SCHEME_STD | DOD_DEVID_MASK)) !=
+ (DOD_DEVID_SCHEME_STD | DOD_DEVID_INTDFP))
continue;
if ((vo_get_device_status(vo->handle) & DCS_ACTIVE) == 0)
@@ -467,38 +468,40 @@ acpi_video_vo_init(UINT32 adr)
ACPI_SERIAL_ASSERT(video);
- switch (adr & DOD_DEVID_MASK) {
+ /* Assume an unknown unit by default. */
+ desc = "unknown output";
+ type = "out";
+ voqh = &other_units;
+
+ switch (adr & (DOD_DEVID_SCHEME_STD | DOD_DEVID_MASK)) {
case DOD_DEVID_MONITOR:
if ((adr & DOD_DEVID_MASK_FULL) == DOD_DEVID_LCD) {
/* DOD_DEVID_LCD is a common, backward compatible ID */
desc = "Internal/Integrated Digital Flat Panel";
type = "lcd";
voqh = &lcd_units;
- } else {
- desc = "VGA CRT or VESA Compatible Analog Monitor";
- type = "crt";
- voqh = &crt_units;
}
break;
- case DOD_DEVID_TV:
+ case DOD_DEVID_SCHEME_STD | DOD_DEVID_MONITOR:
+ desc = "VGA CRT or VESA Compatible Analog Monitor";
+ type = "crt";
+ voqh = &crt_units;
+ break;
+ case DOD_DEVID_SCHEME_STD | DOD_DEVID_TV:
desc = "TV/HDTV or Analog-Video Monitor";
type = "tv";
voqh = &tv_units;
break;
- case DOD_DEVID_EXT:
+ case DOD_DEVID_SCHEME_STD | DOD_DEVID_EXT:
desc = "External Digital Monitor";
type = "ext";
voqh = &ext_units;
break;
- case DOD_DEVID_INTDFP:
+ case DOD_DEVID_SCHEME_STD | DOD_DEVID_INTDFP:
desc = "Internal/Integrated Digital Flat Panel";
type = "lcd";
voqh = &lcd_units;
break;
- default:
- desc = "unknown output";
- type = "out";
- voqh = &other_units;
}
n = 0;
@@ -633,21 +636,25 @@ acpi_video_vo_destroy(struct acpi_video_output *vo
AcpiOsFree(vo->vo_levels);
}
- switch (vo->adr & DOD_DEVID_MASK) {
+ voqh = &other_units;
+
+ switch (vo->adr & (DOD_DEVID_SCHEME_STD | DOD_DEVID_MASK)) {
case DOD_DEVID_MONITOR:
+ if ((vo->adr & DOD_DEVID_MASK_FULL) == DOD_DEVID_LCD)
+ voqh = &lcd_units;
+ break;
+ case DOD_DEVID_SCHEME_STD | DOD_DEVID_MONITOR:
voqh = &crt_units;
break;
- case DOD_DEVID_TV:
+ case DOD_DEVID_SCHEME_STD | DOD_DEVID_TV:
voqh = &tv_units;
break;
- case DOD_DEVID_EXT:
+ case DOD_DEVID_SCHEME_STD | DOD_DEVID_EXT:
voqh = &ext_units;
break;
- case DOD_DEVID_INTDFP:
+ case DOD_DEVID_SCHEME_STD | DOD_DEVID_INTDFP:
voqh = &lcd_units;
break;
- default:
- voqh = &other_units;
}
STAILQ_REMOVE(voqh, vo, acpi_video_output, vo_unit.next);
free(vo, M_ACPIVIDEO);
@@ -906,7 +913,8 @@ vid_enum_outputs_subr(ACPI_HANDLE handle, UINT32 l
for (i = 0; i < argset->dod_pkg->Package.Count; i++) {
if (acpi_PkgInt32(argset->dod_pkg, i, &val) == 0 &&
- (val & DOD_DEVID_MASK_FULL) == adr) {
+ (val & (DOD_DEVID_SCHEME_STD | DOD_DEVID_MASK_FULL)) ==
+ adr) {
argset->callback(handle, val, argset->context);
argset->count++;
}
--
John Baldwin
More information about the freebsd-mobile
mailing list