Esempio n. 1
0
static int
acpi_capm_get_info(apm_info_t aip)
{
	int	acline;
	struct	acpi_battinfo batt;

	aip->ai_infoversion = 1;
	aip->ai_major       = 1;
	aip->ai_minor       = 2;
	aip->ai_status      = apm_softc.active;
	aip->ai_capabilities= 0xff00;	/* XXX unknown */

	if (acpi_acad_get_acline(&acline))
		aip->ai_acline = 0xff;		/* unknown */
	else
		aip->ai_acline = acline;	/* on/off */

	if (acpi_battery_get_battinfo(NULL, &batt)) {
		aip->ai_batt_stat = 0xff;	/* unknown */
		aip->ai_batt_life = 0xff;	/* unknown */
		aip->ai_batt_time = -1;		/* unknown */
		aip->ai_batteries = 0;
	} else {
		aip->ai_batt_stat = acpi_capm_convert_battstate(&batt);
		aip->ai_batt_life = batt.cap;
		aip->ai_batt_time = (batt.min == -1) ? -1 : batt.min * 60;
		aip->ai_batteries = acpi_battery_get_units();
	}

	return (0);
}
static int
acpi_battery_units_sysctl(SYSCTL_HANDLER_ARGS)
{
    int count, error;

    count = acpi_battery_get_units();
    error = sysctl_handle_int(oidp, &count, 0, req);
    return (error);
}
static int
acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg)
{
    union acpi_battery_ioctl_arg *ioctl_arg;
    int error, unit;
    device_t dev;

    /* For commands that use the ioctl_arg struct, validate it first. */
    error = ENXIO;
    unit = 0;
    dev = NULL;
    ioctl_arg = NULL;
    if (IOCPARM_LEN(cmd) == sizeof(*ioctl_arg)) {
	ioctl_arg = (union acpi_battery_ioctl_arg *)addr;
	unit = ioctl_arg->unit;
	if (unit != ACPI_BATTERY_ALL_UNITS)
	    dev = acpi_battery_find_dev(unit);
    }

    /*
     * No security check required: information retrieval only.  If
     * new functions are added here, a check might be required.
     */
    switch (cmd) {
    case ACPIIO_BATT_GET_UNITS:
	*(int *)addr = acpi_battery_get_units();
	error = 0;
	break;
    case ACPIIO_BATT_GET_BATTINFO:
	if (dev != NULL || unit == ACPI_BATTERY_ALL_UNITS) {
	    bzero(&ioctl_arg->battinfo, sizeof(ioctl_arg->battinfo));
	    error = acpi_battery_get_battinfo(dev, &ioctl_arg->battinfo);
	}
	break;
    case ACPIIO_BATT_GET_BIF:
	if (dev != NULL) {
	    bzero(&ioctl_arg->bif, sizeof(ioctl_arg->bif));
	    error = ACPI_BATT_GET_INFO(dev, &ioctl_arg->bif);

	    /*
	     * Remove invalid characters.  Perhaps this should be done
	     * within a convenience function so all callers get the
	     * benefit.
	     */
	    acpi_battery_clean_str(ioctl_arg->bif.model,
		sizeof(ioctl_arg->bif.model));
	    acpi_battery_clean_str(ioctl_arg->bif.serial,
		sizeof(ioctl_arg->bif.serial));
	    acpi_battery_clean_str(ioctl_arg->bif.type,
		sizeof(ioctl_arg->bif.type));
	    acpi_battery_clean_str(ioctl_arg->bif.oeminfo,
		sizeof(ioctl_arg->bif.oeminfo));
	}
	break;
    case ACPIIO_BATT_GET_BST:
	if (dev != NULL) {
	    bzero(&ioctl_arg->bst, sizeof(ioctl_arg->bst));
	    error = ACPI_BATT_GET_STATUS(dev, &ioctl_arg->bst);
	}
	break;
    default:
	error = EINVAL;
    }

    return (error);
}
Esempio n. 4
0
static int
acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg)
{
    union acpi_battery_ioctl_arg *ioctl_arg;
    int error, unit;
    device_t dev;


    /*
     * Giant is acquired to work around a reference counting bug in ACPICA
     * versions prior to 20130328.  If not for that bug this function could
     * be executed concurrently without any problems.
     * The bug is in acpi_BatteryIsPresent -> AcpiGetObjectInfo call tree,
     * where AcpiUtExecute_HID, AcpiUtExecute_UID, etc are executed without
     * protection of any ACPICA lock and may concurrently call
     * AcpiUtRemoveReference on a battery object.
     */
    mtx_lock(&Giant);

    /* For commands that use the ioctl_arg struct, validate it first. */
    error = ENXIO;
    unit = 0;
    dev = NULL;
    ioctl_arg = NULL;
    if (IOCPARM_LEN(cmd) == sizeof(*ioctl_arg)) {
	ioctl_arg = (union acpi_battery_ioctl_arg *)addr;
	unit = ioctl_arg->unit;
	if (unit != ACPI_BATTERY_ALL_UNITS)
	    dev = acpi_battery_find_dev(unit);
    }

    /*
     * No security check required: information retrieval only.  If
     * new functions are added here, a check might be required.
     */
    switch (cmd) {
    case ACPIIO_BATT_GET_UNITS:
	*(int *)addr = acpi_battery_get_units();
	error = 0;
	break;
    case ACPIIO_BATT_GET_BATTINFO:
	if (dev != NULL || unit == ACPI_BATTERY_ALL_UNITS) {
	    bzero(&ioctl_arg->battinfo, sizeof(ioctl_arg->battinfo));
	    error = acpi_battery_get_battinfo(dev, &ioctl_arg->battinfo);
	}
	break;
    case ACPIIO_BATT_GET_BIF:
	if (dev != NULL) {
	    bzero(&ioctl_arg->bif, sizeof(ioctl_arg->bif));
	    error = ACPI_BATT_GET_INFO(dev, &ioctl_arg->bif);

	    /*
	     * Remove invalid characters.  Perhaps this should be done
	     * within a convenience function so all callers get the
	     * benefit.
	     */
	    acpi_battery_clean_str(ioctl_arg->bif.model,
		sizeof(ioctl_arg->bif.model));
	    acpi_battery_clean_str(ioctl_arg->bif.serial,
		sizeof(ioctl_arg->bif.serial));
	    acpi_battery_clean_str(ioctl_arg->bif.type,
		sizeof(ioctl_arg->bif.type));
	    acpi_battery_clean_str(ioctl_arg->bif.oeminfo,
		sizeof(ioctl_arg->bif.oeminfo));
	}
	break;
    case ACPIIO_BATT_GET_BST:
	if (dev != NULL) {
	    bzero(&ioctl_arg->bst, sizeof(ioctl_arg->bst));
	    error = ACPI_BATT_GET_STATUS(dev, &ioctl_arg->bst);
	}
	break;
    default:
	error = EINVAL;
    }

    mtx_unlock(&Giant);
    return (error);
}