-/* $OpenBSD: sysctl.c,v 1.258 2021/07/12 15:09:19 beck Exp $ */
+/* $OpenBSD: sysctl.c,v 1.259 2023/05/17 22:12:51 kettenis Exp $ */
/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */
/*
struct ctlname audioname[] = CTL_KERN_AUDIO_NAMES;
struct ctlname videoname[] = CTL_KERN_VIDEO_NAMES;
struct ctlname witnessname[] = CTL_KERN_WITNESS_NAMES;
+struct ctlname batteryname[] = CTL_HW_BATTERY_NAMES;
char names[BUFSIZ];
int lastused;
int sysctl_audio(char *, char **, int *, int, int *);
int sysctl_video(char *, char **, int *, int, int *);
int sysctl_witness(char *, char **, int *, int, int *);
+int sysctl_battery(char *, char **, int *, int, int *);
void vfsinit(void);
char *equ = "=";
if (len < 0)
return;
break;
+ case HW_BATTERY:
+ len = sysctl_battery(string, &bufp, mib, flags, &type);
+ if (len < 0)
+ return;
+ break;
case HW_PHYSMEM:
case HW_USERMEM:
/*
struct list audiolist = { audioname, KERN_AUDIO_MAXID };
struct list videolist = { videoname, KERN_VIDEO_MAXID };
struct list witnesslist = { witnessname, KERN_WITNESS_MAXID };
+struct list batterylist = { batteryname, HW_BATTERY_MAXID };
/*
* handle vfs namei cache statistics
return (3);
}
+/*
+ * Handle battery support
+ */
+int
+sysctl_battery(char *string, char **bufpp, int mib[], int flags,
+ int *typep)
+{
+ int indx;
+
+ if (*bufpp == NULL) {
+ listall(string, &batterylist);
+ return (-1);
+ }
+ if ((indx = findname(string, "third", bufpp, &batterylist)) == -1)
+ return (-1);
+ mib[2] = indx;
+ *typep = batterylist.list[indx].ctl_type;
+ return (3);
+}
+
/*
* Scan a list of names searching for a particular name.
*/
-/* $OpenBSD: kern_sysctl.c,v 1.412 2023/05/04 09:40:36 mvs Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.413 2023/05/17 22:12:51 kettenis Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
int sysctl_video(int *, u_int, void *, size_t *, void *, size_t);
int sysctl_cpustats(int *, u_int, void *, size_t *, void *, size_t);
int sysctl_utc_offset(void *, size_t *, void *, size_t);
+int sysctl_hwbattery(int *, u_int, void *, size_t *, void *, size_t);
void fill_file(struct kinfo_file *, struct file *, struct filedesc *, int,
struct vnode *, struct process *, struct proc *, struct socket *, int);
extern char machine[], cpu_model[];
int err, cpuspeed;
- /* all sysctl names at this level except sensors are terminal */
- if (name[0] != HW_SENSORS && namelen != 1)
+ /*
+ * all sysctl names at this level except sensors and battery
+ * are terminal
+ */
+ if (name[0] != HW_SENSORS && name[0] != HW_BATTERY && namelen != 1)
return (ENOTDIR); /* overloaded */
switch (name[0]) {
#ifdef __HAVE_CPU_TOPOLOGY
case HW_SMT:
return (sysctl_hwsmt(oldp, oldlenp, newp, newlen));
+#endif
+#ifndef SMALL_KERNEL
+ case HW_BATTERY:
+ return (sysctl_hwbattery(name + 1, namelen - 1, oldp, oldlenp,
+ newp, newlen));
#endif
default:
return sysctl_bounded_arr(hw_vars, nitems(hw_vars), name,
/* NOTREACHED */
}
+#ifndef SMALL_KERNEL
+
+int hw_battery_chargemode;
+int hw_battery_chargestart;
+int hw_battery_chargestop;
+int (*hw_battery_setchargemode)(int);
+int (*hw_battery_setchargestart)(int);
+int (*hw_battery_setchargestop)(int);
+
+int
+sysctl_hwchargemode(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
+{
+ int mode = hw_battery_chargemode;
+ int error;
+
+ if (!hw_battery_setchargemode)
+ return EOPNOTSUPP;
+
+ error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+ &mode, -1, 1);
+ if (error)
+ return error;
+
+ if (newp != NULL)
+ error = hw_battery_setchargemode(mode);
+
+ return error;
+}
+
+int
+sysctl_hwchargestart(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
+{
+ int start = hw_battery_chargestart;
+ int error;
+
+ if (!hw_battery_setchargestart)
+ return EOPNOTSUPP;
+
+ error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+ &start, 0, 100);
+ if (error)
+ return error;
+
+ if (newp != NULL)
+ error = hw_battery_setchargestart(start);
+
+ return error;
+}
+
+int
+sysctl_hwchargestop(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
+{
+ int stop = hw_battery_chargestop;
+ int error;
+
+ if (!hw_battery_setchargestart)
+ return EOPNOTSUPP;
+
+ error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+ &stop, 0, 100);
+ if (error)
+ return error;
+
+ if (newp != NULL)
+ error = hw_battery_setchargestop(stop);
+
+ return error;
+}
+
+int
+sysctl_hwbattery(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+ void *newp, size_t newlen)
+{
+ if (namelen != 1)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case HW_BATTERY_CHARGEMODE:
+ return (sysctl_hwchargemode(oldp, oldlenp, newp, newlen));
+ case HW_BATTERY_CHARGESTART:
+ return (sysctl_hwchargestart(oldp, oldlenp, newp, newlen));
+ case HW_BATTERY_CHARGESTOP:
+ return (sysctl_hwchargestop(oldp, oldlenp, newp, newlen));
+ default:
+ return (EOPNOTSUPP);
+ }
+ /* NOTREACHED */
+}
+
+#endif
+
#ifdef DEBUG_SYSCTL
/*
* Debugging related system variables.
-/* $OpenBSD: sysctl.h,v 1.232 2023/01/07 05:24:58 guenther Exp $ */
+/* $OpenBSD: sysctl.h,v 1.233 2023/05/17 22:12:51 kettenis Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
#define HW_SMT 24 /* int: enable SMT/HT/CMT */
#define HW_NCPUONLINE 25 /* int: number of cpus being used */
#define HW_POWER 26 /* int: machine has wall-power */
-#define HW_MAXID 27 /* number of valid hw ids */
+#define HW_BATTERY 27 /* node: battery */
+#define HW_MAXID 30 /* number of valid hw ids */
#define CTL_HW_NAMES { \
{ 0, 0 }, \
{ "smt", CTLTYPE_INT }, \
{ "ncpuonline", CTLTYPE_INT }, \
{ "power", CTLTYPE_INT }, \
+ { "battery", CTLTYPE_NODE }, \
+}
+
+/*
+ * HW_BATTERY
+ */
+#define HW_BATTERY_CHARGEMODE 1 /* int: battery charging mode */
+#define HW_BATTERY_CHARGESTART 2 /* int: battery start charge percent */
+#define HW_BATTERY_CHARGESTOP 3 /* int: battery stop charge percent */
+#define HW_BATTERY_MAXID 4
+
+#define CTL_HW_BATTERY_NAMES { \
+ { 0, 0 }, \
+ { "chargemode", CTLTYPE_INT }, \
+ { "chargestart", CTLTYPE_INT }, \
+ { "chargestop", CTLTYPE_INT }, \
}
/*