/* * Get the current temperature. */ static int acpi_tz_get_temperature(struct acpi_tz_softc *sc) { int temp; ACPI_STATUS status; ACPI_FUNCTION_NAME ("acpi_tz_get_temperature"); /* Evaluate the thermal zone's _TMP method. */ status = acpi_GetInteger(sc->tz_handle, acpi_tz_tmp_name, &temp); if (ACPI_FAILURE(status)) { ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), "error fetching current temperature -- %s\n", AcpiFormatException(status)); return (FALSE); } /* Check it for validity. */ acpi_tz_sanity(sc, &temp, acpi_tz_tmp_name); if (temp == -1) return (FALSE); ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "got %d.%dC\n", TZ_KELVTOC(temp))); sc->tz_temperature = temp; return (TRUE); }
static void acpi_acad_get_status(void *context) { struct acpi_acad_softc *sc; device_t dev; ACPI_HANDLE h; int newstatus; dev = context; sc = device_get_softc(dev); h = acpi_get_handle(dev); newstatus = -1; acpi_GetInteger(h, "_PSR", &newstatus); /* If status is valid and has changed, notify the system. */ ACPI_SERIAL_BEGIN(acad); if (newstatus != -1 && sc->status != newstatus) { sc->status = newstatus; power_profile_set_state(newstatus ? POWER_PROFILE_PERFORMANCE : POWER_PROFILE_ECONOMY); ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "%s Line\n", newstatus ? "On" : "Off"); acpi_UserNotify("ACAD", h, newstatus); } ACPI_SERIAL_END(acad); }
static int acpi_sony_attach(device_t dev) { struct acpi_sony_softc *sc; int i; sc = device_get_softc(dev); acpi_GetInteger(acpi_get_handle(dev), ACPI_SONY_GET_PID, &sc->pid); device_printf(dev, "PID %x\n", sc->pid); for (i = 0 ; acpi_sony_oids[i].nodename != NULL; i++) { if (acpi_sony_oids[i].setmethod != NULL) { SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), i, acpi_sony_oids[i].nodename , CTLTYPE_INT | CTLFLAG_RW, dev, i, sysctl_acpi_sony_gen_handler, "I", acpi_sony_oids[i].comment); } else { SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), i, acpi_sony_oids[i].nodename , CTLTYPE_INT | CTLFLAG_RD, dev, i, sysctl_acpi_sony_gen_handler, "I", acpi_sony_oids[i].comment); } } return (0); }
static int acpi_smbat_attach(device_t dev) { struct acpi_smbat_softc *sc; uint32_t base; sc = device_get_softc(dev); if (ACPI_FAILURE(acpi_GetInteger(acpi_get_handle(dev), "_EC", &base))) { device_printf(dev, "cannot get EC base address\n"); return (ENXIO); } sc->sb_base_addr = (base >> 8) & 0xff; /* XXX Only works with one EC, but nearly all systems only have one. */ sc->ec_dev = devclass_get_device(devclass_find("acpi_ec"), 0); if (sc->ec_dev == NULL) { device_printf(dev, "cannot find EC device\n"); return (ENXIO); } timespecclear(&sc->bif_lastupdated); timespecclear(&sc->bst_lastupdated); if (acpi_battery_register(dev) != 0) { device_printf(dev, "cannot register battery\n"); return (ENXIO); } return (0); }
static ACPI_STATUS acpi_pci_save_handle(ACPI_HANDLE handle, UINT32 level, void *context, void **status) { struct acpi_pci_devinfo *dinfo; device_t *devlist; int devcount, i, func, slot; UINT32 address; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); if (ACPI_FAILURE(acpi_GetInteger(handle, "_ADR", &address))) return_ACPI_STATUS (AE_OK); slot = ACPI_ADR_PCI_SLOT(address); func = ACPI_ADR_PCI_FUNC(address); if (device_get_children((device_t)context, &devlist, &devcount) != 0) return_ACPI_STATUS (AE_OK); for (i = 0; i < devcount; i++) { dinfo = device_get_ivars(devlist[i]); if (dinfo->ap_dinfo.cfg.func == func && dinfo->ap_dinfo.cfg.slot == slot) { dinfo->ap_handle = handle; acpi_pci_update_device(handle, devlist[i]); break; } } free(devlist, M_TEMP); return_ACPI_STATUS (AE_OK); }
/* * Look for an ECDT and if we find one, set up default GPE and * space handlers to catch attempts to access EC space before * we have a real driver instance in place. * * TODO: Some old Gateway laptops need us to fake up an ECDT or * otherwise attach early so that _REG methods can run. */ void acpi_ec_ecdt_probe(device_t parent) { ACPI_TABLE_ECDT *ecdt; ACPI_STATUS status; device_t child; ACPI_HANDLE h; struct acpi_ec_params *params; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); /* Find and validate the ECDT. */ status = AcpiGetTable(ACPI_SIG_ECDT, 1, (ACPI_TABLE_HEADER **)&ecdt); if (ACPI_FAILURE(status) || ecdt->Control.BitWidth != 8 || ecdt->Data.BitWidth != 8) { return; } /* Create the child device with the given unit number. */ child = BUS_ADD_CHILD(parent, parent, 0, "acpi_ec", ecdt->Uid); if (child == NULL) { kprintf("%s: can't add child\n", __func__); return; } /* Find and save the ACPI handle for this device. */ status = AcpiGetHandle(NULL, ecdt->Id, &h); if (ACPI_FAILURE(status)) { device_delete_child(parent, child); kprintf("%s: can't get handle\n", __func__); return; } acpi_set_handle(child, h); /* Set the data and CSR register addresses. */ bus_set_resource(child, SYS_RES_IOPORT, 0, ecdt->Data.Address, /*count*/1, -1); bus_set_resource(child, SYS_RES_IOPORT, 1, ecdt->Control.Address, /*count*/1, -1); /* * Store values for the probe/attach routines to use. Store the * ECDT GPE bit and set the global lock flag according to _GLK. * Note that it is not perfectly correct to be evaluating a method * before initializing devices, but in practice this function * should be safe to call at this point. */ params = kmalloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO); params->gpe_handle = NULL; params->gpe_bit = ecdt->Gpe; params->uid = ecdt->Uid; acpi_GetInteger(h, "_GLK", ¶ms->glk); acpi_set_private(child, params); /* Finish the attach process. */ if (device_probe_and_attach(child) != 0) device_delete_child(parent, child); }
/* * Query the get methods to determine what functionality is available * from the hardware function hotkeys. */ static uint8_t acpi_fujitsu_check_hardware(struct acpi_fujitsu_softc *sc) { int val; ACPI_SERIAL_ASSERT(fujitsu); /* save the hotkey bitmask */ if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->gsif.name, &(sc->gsif.value)))) { sc->gsif.exists = 0; device_printf(sc->dev, "Couldn't query bitmask value\n"); } else { sc->gsif.exists = 1; } /* System Volume Level */ if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->gvol.name, &val))) { sc->gvol.exists = 0; } else { sc->gvol.exists = 1; } if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->gbll.name, &val))) { sc->gbll.exists = 0; } else { sc->gbll.exists = 1; } if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->ghks.name, &val))) { sc->ghks.exists = 0; } else { sc->ghks.exists = 1; } if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->gmou.name, &val))) { sc->gmou.exists = 0; } else { sc->gmou.exists = 1; } if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->rbll.name, &val))) { sc->rbll.exists = 0; } else { sc->rbll.exists = 1; } if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->rvol.name, &val))) { sc->rvol.exists = 0; } else { sc->rvol.exists = 1; } return (TRUE); }
static void acpi_dock_get_info(device_t dev) { struct acpi_dock_softc *sc; ACPI_HANDLE h; sc = device_get_softc(dev); h = acpi_get_handle(dev); if (ACPI_FAILURE(acpi_GetInteger(h, "_STA", &sc->_sta))) sc->_sta = ACPI_DOCK_STATUS_UNKNOWN; if (ACPI_FAILURE(acpi_GetInteger(h, "_BDN", &sc->_bdn))) sc->_bdn = ACPI_DOCK_STATUS_UNKNOWN; if (ACPI_FAILURE(acpi_GetInteger(h, "_UID", &sc->_uid))) sc->_uid = ACPI_DOCK_STATUS_UNKNOWN; ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), "_STA: %04x, _BDN: %04x, _UID: %04x\n", sc->_sta, sc->_bdn, sc->_uid); }
static int acpi_fujitsu_method_get(struct acpi_fujitsu_softc *sc, int method) { struct int_nameval nv; ACPI_STATUS status; ACPI_SERIAL_ASSERT(fujitsu); switch (method) { case METHOD_GBLL: nv = sc->gbll; break; case METHOD_GBLS: nv = sc->gbls; break; case METHOD_GMOU: nv = sc->gmou; break; case METHOD_GVOL: case METHOD_MUTE: nv = sc->gvol; break; case METHOD_GHKS: nv = sc->ghks; break; case METHOD_GSIF: nv = sc->gsif; break; case METHOD_RBLL: nv = sc->rbll; break; case METHOD_RVOL: nv = sc->rvol; break; default: return (FALSE); } if(!nv.exists) return (EINVAL); status = acpi_GetInteger(sc->handle, nv.name, &nv.value); if (ACPI_FAILURE(status)) { device_printf(sc->dev, "Couldn't query method (%s)\n", nv.name); return (FALSE); } if (method == METHOD_MUTE) { sc->bIsMuted = (uint8_t)((nv.value & VOLUME_MUTE_BIT) != 0); return (sc->bIsMuted); } nv.value &= GENERAL_SETTING_BITS; return (nv.value); }
/* * Read/debug-print a parameter, default it to -1. */ static void acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data) { ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); if (ACPI_FAILURE(acpi_GetInteger(sc->tz_handle, node, data))) { *data = -1; } else { ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "%s.%s = %d\n", acpi_name(sc->tz_handle), node, *data)); } return_VOID; }
static int sysctl_acpi_sony_gen_handler(SYSCTL_HANDLER_ARGS) { device_t dev = arg1; int function = oidp->oid_arg2; int error = 0, val; acpi_GetInteger(acpi_get_handle(dev), acpi_sony_oids[function].getmethod, &val); error = sysctl_handle_int(oidp, &val, 0, req); if (error || !req->newptr || !acpi_sony_oids[function].setmethod) return (error); acpi_SetInteger(acpi_get_handle(dev), acpi_sony_oids[function].setmethod, val); return (0); }
/* * Find the highest currently-supported performance state. * This can be called at runtime (e.g., due to a docking event) at * the request of a Notify on the processor object. */ static void acpi_px_available(struct acpi_perf_softc *sc) { ACPI_STATUS status; struct cf_setting set; status = acpi_GetInteger(sc->handle, "_PPC", &sc->px_max_avail); /* If the old state is too high, set current state to the new max. */ if (ACPI_SUCCESS(status)) { if (sc->px_curr_state != CPUFREQ_VAL_UNKNOWN && sc->px_curr_state > sc->px_max_avail) { acpi_px_to_set(sc->dev, &sc->px_states[sc->px_max_avail], &set); acpi_px_set(sc->dev, &set); } } else sc->px_max_avail = 0; }
static int acpi_pci_child_location_str_method(device_t cbdev, device_t child, char *buf, size_t buflen) { struct acpi_pci_devinfo *dinfo = device_get_ivars(child); int pxm; char buf2[32]; pci_child_location_str_method(cbdev, child, buf, buflen); if (dinfo->ap_handle) { strlcat(buf, " handle=", buflen); strlcat(buf, acpi_name(dinfo->ap_handle), buflen); if (ACPI_SUCCESS(acpi_GetInteger(dinfo->ap_handle, "_PXM", &pxm))) { snprintf(buf2, 32, " _PXM=%d", pxm); strlcat(buf, buf2, buflen); } } return (0); }
static void acpi_lid_notify_status_changed(void *arg) { struct acpi_lid_softc *sc; struct acpi_softc *acpi_sc; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = (struct acpi_lid_softc *)arg; ACPI_SERIAL_BEGIN(lid); /* * Evaluate _LID and check the return value, update lid status. * Zero: The lid is closed * Non-zero: The lid is open */ status = acpi_GetInteger(sc->lid_handle, "_LID", &sc->lid_status); if (ACPI_FAILURE(status)) goto out; acpi_sc = acpi_device_get_parent_softc(sc->lid_dev); if (acpi_sc == NULL) goto out; ACPI_VPRINT(sc->lid_dev, acpi_sc, "Lid %s\n", sc->lid_status ? "opened" : "closed"); acpi_UserNotify("Lid", sc->lid_handle, sc->lid_status); if (sc->lid_status == 0) EVENTHANDLER_INVOKE(acpi_sleep_event, acpi_sc->acpi_lid_switch_sx); else EVENTHANDLER_INVOKE(acpi_wakeup_event, acpi_sc->acpi_lid_switch_sx); out: ACPI_SERIAL_END(lid); return_VOID; }
static int ipmi_acpi_attach(device_t dev) { ACPI_HANDLE devh; const char *mode; struct ipmi_get_info info; struct ipmi_softc *sc = device_get_softc(dev); int count, error, flags, i, type; int interface_type = 0, interface_version = 0; error = 0; devh = acpi_get_handle(dev); if (ACPI_FAILURE(acpi_GetInteger(devh, "_IFT", &interface_type))) return (ENXIO); if (ACPI_FAILURE(acpi_GetInteger(devh, "_SRV", &interface_version))) return (ENXIO); switch (interface_type) { case KCS_MODE: count = 2; mode = "KCS"; break; case SMIC_MODE: count = 3; mode = "SMIC"; break; case BT_MODE: device_printf(dev, "BT interface not supported\n"); return (ENXIO); case SSIF_MODE: if (ACPI_FAILURE(acpi_GetInteger(devh, "_ADR", &flags))) return (ENXIO); info.address = flags; device_printf(dev, "SSIF interface not supported on ACPI\n"); return (0); default: return (ENXIO); } if (bus_get_resource(dev, SYS_RES_IOPORT, 0, NULL, NULL) == 0) type = SYS_RES_IOPORT; else if (bus_get_resource(dev, SYS_RES_MEMORY, 0, NULL, NULL) == 0) type = SYS_RES_MEMORY; else { device_printf(dev, "unknown resource type\n"); return (ENXIO); } sc->ipmi_io_rid = 0; sc->ipmi_io_res[0] = bus_alloc_resource_any(dev, type, &sc->ipmi_io_rid, RF_ACTIVE); sc->ipmi_io_type = type; sc->ipmi_io_spacing = 1; if (sc->ipmi_io_res[0] == NULL) { device_printf(dev, "couldn't configure I/O resource\n"); return (ENXIO); } /* If we have multiple resources, allocate up to MAX_RES. */ for (i = 1; i < MAX_RES; i++) { sc->ipmi_io_rid = i; sc->ipmi_io_res[i] = bus_alloc_resource_any(dev, type, &sc->ipmi_io_rid, RF_ACTIVE); if (sc->ipmi_io_res[i] == NULL) break; } sc->ipmi_io_rid = 0; /* If we have multiple resources, make sure we have enough of them. */ if (sc->ipmi_io_res[1] != NULL && sc->ipmi_io_res[count - 1] == NULL) { device_printf(dev, "too few I/O resources\n"); error = ENXIO; goto bad; } device_printf(dev, "%s mode found at %s 0x%jx on %s\n", mode, type == SYS_RES_IOPORT ? "io" : "mem", (uintmax_t)rman_get_start(sc->ipmi_io_res[0]), device_get_name(device_get_parent(dev))); sc->ipmi_dev = dev; /* * Setup an interrupt if we have an interrupt resource. We * don't support GPE interrupts via _GPE yet. */ sc->ipmi_irq_rid = 0; sc->ipmi_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->ipmi_irq_rid, RF_SHAREABLE | RF_ACTIVE); /* Warn if _GPE exists. */ if (ACPI_SUCCESS(AcpiEvaluateObject(devh, "_GPE", NULL, NULL))) device_printf(dev, "_GPE support not implemented\n"); /* * We assume an alignment of 1 byte as currently the IPMI spec * doesn't provide any way to determine the alignment via ACPI. */ switch (interface_type) { case KCS_MODE: error = ipmi_kcs_attach(sc); if (error) goto bad; break; case SMIC_MODE: error = ipmi_smic_attach(sc); if (error) goto bad; break; } error = ipmi_attach(dev); if (error) goto bad; return (0); bad: ipmi_release_resources(dev); return (error); }
static int acpi_ec_probe(device_t dev) { ACPI_BUFFER buf; ACPI_HANDLE h; ACPI_OBJECT *obj; ACPI_STATUS status; device_t peer; char desc[64]; int ecdt; int ret; struct acpi_ec_params *params; static char *ec_ids[] = { "PNP0C09", NULL }; /* Check that this is a device and that EC is not disabled. */ if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("ec")) return (ENXIO); /* * If probed via ECDT, set description and continue. Otherwise, * we can access the namespace and make sure this is not a * duplicate probe. */ ret = ENXIO; ecdt = 0; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; params = acpi_get_private(dev); if (params != NULL) { ecdt = 1; ret = 0; } else if (ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids)) { params = kmalloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO); h = acpi_get_handle(dev); /* * Read the unit ID to check for duplicate attach and the * global lock value to see if we should acquire it when * accessing the EC. */ status = acpi_GetInteger(h, "_UID", ¶ms->uid); if (ACPI_FAILURE(status)) params->uid = 0; status = acpi_GetInteger(h, "_GLK", ¶ms->glk); if (ACPI_FAILURE(status)) params->glk = 0; /* * Evaluate the _GPE method to find the GPE bit used by the EC to * signal status (SCI). If it's a package, it contains a reference * and GPE bit, similar to _PRW. */ status = AcpiEvaluateObject(h, "_GPE", NULL, &buf); if (ACPI_FAILURE(status)) { device_printf(dev, "can't evaluate _GPE - %s\n", AcpiFormatException(status)); goto out; } obj = (ACPI_OBJECT *)buf.Pointer; if (obj == NULL) goto out; switch (obj->Type) { case ACPI_TYPE_INTEGER: params->gpe_handle = NULL; params->gpe_bit = obj->Integer.Value; break; case ACPI_TYPE_PACKAGE: if (!ACPI_PKG_VALID(obj, 2)) goto out; params->gpe_handle = acpi_GetReference(NULL, &obj->Package.Elements[0]); if (params->gpe_handle == NULL || acpi_PkgInt32(obj, 1, ¶ms->gpe_bit) != 0) goto out; break; default: device_printf(dev, "_GPE has invalid type %d\n", obj->Type); goto out; } /* Store the values we got from the namespace for attach. */ acpi_set_private(dev, params); /* * Check for a duplicate probe. This can happen when a probe * via ECDT succeeded already. If this is a duplicate, disable * this device. */ peer = devclass_get_device(acpi_ec_devclass, params->uid); if (peer == NULL || !device_is_alive(peer)) ret = 0; else device_disable(dev); } out: if (ret == 0) { ksnprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s", params->gpe_bit, (params->glk) ? ", GLK" : "", ecdt ? ", ECDT" : ""); device_set_desc_copy(dev, desc); } if (ret > 0 && params) kfree(params, M_TEMP); if (buf.Pointer) AcpiOsFree(buf.Pointer); return (ret); }
/* * Query each of the ACPI control methods that contain information we're * interested in. We check the return values from the control methods and * adjust any state variables if they should be adjusted. */ static uint8_t acpi_fujitsu_update(struct acpi_fujitsu_softc *sc) { int changed; struct acpi_softc *acpi_sc; acpi_sc = acpi_device_get_parent_softc(sc->dev); ACPI_SERIAL_ASSERT(fujitsu); if(sc->gsif.exists) changed = sc->gsif.value & acpi_fujitsu_method_get(sc,METHOD_GHKS); else changed = 0; /* System Volume Level */ if(sc->gvol.exists) { if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->gvol.name, &(sc->gvol.value)))) { device_printf(sc->dev, "Couldn't query volume level\n"); return (FALSE); } if (changed & VOLUME_CHANGED) { sc->bIsMuted = (uint8_t)((sc->gvol.value & VOLUME_MUTE_BIT) != 0); /* Clear the modification bit */ sc->gvol.value &= VOLUME_SETTING_BITS; if (sc->bIsMuted) { acpi_UserNotify("FUJITSU", sc->handle, FN_MUTE); ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now mute\n"); } else ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now %d\n", sc->gvol.value); acpi_UserNotify("FUJITSU", sc->handle, FN_VOLUME); } } /* Internal mouse pointer (eraserhead) */ if(sc->gmou.exists) { if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->gmou.name, &(sc->gmou.value)))) { device_printf(sc->dev, "Couldn't query pointer state\n"); return (FALSE); } if (changed & MOUSE_CHANGED) { sc->bIntPtrEnabled = (uint8_t)(sc->gmou.value & 0x1); /* Clear the modification bit */ sc->gmou.value &= MOUSE_SETTING_BITS; /* Set the value in case it is not hardware controlled */ acpi_fujitsu_method_set(sc, METHOD_GMOU, sc->gmou.value); acpi_UserNotify("FUJITSU", sc->handle, FN_POINTER_ENABLE); ACPI_VPRINT(sc->dev, acpi_sc, "Internal pointer is now %s\n", (sc->bIntPtrEnabled) ? "enabled" : "disabled"); } } /* Screen Brightness Level P8XXX */ if(sc->gbls.exists) { if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->gbls.name, &(sc->gbls.value)))) { device_printf(sc->dev, "Couldn't query P8XXX brightness level\n"); return (FALSE); } if (changed & BRIGHT_CHANGED) { /* No state to record here. */ /* Clear the modification bit */ sc->gbls.value &= BRIGHTNESS_SETTING_BITS; /* Set the value in case it is not hardware controlled */ acpi_fujitsu_method_set(sc, METHOD_GBLS, sc->gbls.value); acpi_UserNotify("FUJITSU", sc->handle, FN_LCD_BRIGHTNESS); ACPI_VPRINT(sc->dev, acpi_sc, "P8XXX Brightness level is now %d\n", sc->gbls.value); } } /* Screen Brightness Level */ if(sc->gbll.exists) { if (ACPI_FAILURE(acpi_GetInteger(sc->handle, sc->gbll.name, &(sc->gbll.value)))) { device_printf(sc->dev, "Couldn't query brightness level\n"); return (FALSE); } if (changed & BRIGHT_CHANGED) { /* No state to record here. */ /* Clear the modification bit */ sc->gbll.value &= BRIGHTNESS_SETTING_BITS; acpi_UserNotify("FUJITSU", sc->handle, FN_LCD_BRIGHTNESS); ACPI_VPRINT(sc->dev, acpi_sc, "Brightness level is now %d\n", sc->gbll.value); } } sc->lastValChanged = changed; return (TRUE); }
static int bytgpio_attach(device_t dev) { struct bytgpio_softc *sc; ACPI_STATUS status; int uid; int pin; uint32_t reg, val; sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_handle = acpi_get_handle(dev); status = acpi_GetInteger(sc->sc_handle, "_UID", &uid); if (ACPI_FAILURE(status)) { device_printf(dev, "failed to read _UID\n"); return (ENXIO); } BYTGPIO_LOCK_INIT(sc); switch (uid) { case SCORE_UID: sc->sc_npins = SCORE_PINS; sc->sc_bank_prefix = SCORE_BANK_PREFIX; sc->sc_pinpad_map = bytgpio_score_pins; break; case NCORE_UID: sc->sc_npins = NCORE_PINS; sc->sc_bank_prefix = NCORE_BANK_PREFIX; sc->sc_pinpad_map = bytgpio_ncore_pins; break; case SUS_UID: sc->sc_npins = SUS_PINS; sc->sc_bank_prefix = SUS_BANK_PREFIX; sc->sc_pinpad_map = bytgpio_sus_pins; break; default: device_printf(dev, "invalid _UID value: %d\n", uid); goto error; } sc->sc_pad_funcs = malloc(sizeof(int)*sc->sc_npins, M_DEVBUF, M_WAITOK | M_ZERO); sc->sc_mem_rid = 0; sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev, SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE); if (sc->sc_mem_res == NULL) { device_printf(dev, "can't allocate resource\n"); goto error; } for (pin = 0; pin < sc->sc_npins; pin++) { reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PCONF0); val = bytgpio_read_4(sc, reg); sc->sc_pad_funcs[pin] = val & BYTGPIO_PCONF0_FUNC_MASK; } sc->sc_busdev = gpiobus_attach_bus(dev); if (sc->sc_busdev == NULL) { BYTGPIO_LOCK_DESTROY(sc); bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, sc->sc_mem_res); return (ENXIO); } return (0); error: BYTGPIO_LOCK_DESTROY(sc); return (ENXIO); }
static int acpi_pcib_acpi_attach(device_t dev) { struct acpi_hpcib_softc *sc; ACPI_STATUS status; static int bus0_seen = 0; u_int addr, slot, func, busok; uint8_t busno; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->ap_dev = dev; sc->ap_handle = acpi_get_handle(dev); /* * Get our segment number by evaluating _SEG * It's OK for this to not exist. */ status = acpi_GetInteger(sc->ap_handle, "_SEG", &sc->ap_segment); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { device_printf(dev, "could not evaluate _SEG - %s\n", AcpiFormatException(status)); return_VALUE (ENXIO); } /* If it's not found, assume 0. */ sc->ap_segment = 0; } /* * Get our base bus number by evaluating _BBN. * If this doesn't work, we assume we're bus number 0. * * XXX note that it may also not exist in the case where we are * meant to use a private configuration space mechanism for this bus, * so we should dig out our resources and check to see if we have * anything like that. How do we do this? * XXX If we have the requisite information, and if we don't think the * default PCI configuration space handlers can deal with this bus, * we should attach our own handler. * XXX invoke _REG on this for the PCI config space address space? * XXX It seems many BIOS's with multiple Host-PCI bridges do not set * _BBN correctly. They set _BBN to zero for all bridges. Thus, * if _BBN is zero and PCI bus 0 already exists, we try to read our * bus number from the configuration registers at address _ADR. * We only do this for domain/segment 0 in the hopes that this is * only needed for old single-domain machines. */ status = acpi_GetInteger(sc->ap_handle, "_BBN", &sc->ap_bus); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { device_printf(dev, "could not evaluate _BBN - %s\n", AcpiFormatException(status)); return_VALUE (ENXIO); } else { /* If it's not found, assume 0. */ sc->ap_bus = 0; } } /* * If this is segment 0, the bus is zero, and PCI bus 0 already * exists, read the bus number via PCI config space. */ busok = 1; if (sc->ap_segment == 0 && sc->ap_bus == 0 && bus0_seen) { busok = 0; status = acpi_GetInteger(sc->ap_handle, "_ADR", &addr); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { device_printf(dev, "could not evaluate _ADR - %s\n", AcpiFormatException(status)); return_VALUE (ENXIO); } else device_printf(dev, "couldn't find _ADR\n"); } else { /* XXX: We assume bus 0. */ slot = ACPI_ADR_PCI_SLOT(addr); func = ACPI_ADR_PCI_FUNC(addr); if (bootverbose) device_printf(dev, "reading config registers from 0:%d:%d\n", slot, func); if (host_pcib_get_busno(pci_cfgregread, 0, slot, func, &busno) == 0) device_printf(dev, "couldn't read bus number from cfg space\n"); else { sc->ap_bus = busno; busok = 1; } } } /* * If nothing else worked, hope that ACPI at least lays out the * host-PCI bridges in order and that as a result our unit number * is actually our bus number. There are several reasons this * might not be true. */ if (busok == 0) { sc->ap_bus = device_get_unit(dev); device_printf(dev, "trying bus number %d\n", sc->ap_bus); } /* If this is bus 0 on segment 0, note that it has been seen already. */ if (sc->ap_segment == 0 && sc->ap_bus == 0) bus0_seen = 1; return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_bus)); }