Index: include/Makefile =================================================================== --- include/Makefile (revision 221997) +++ include/Makefile (working copy) @@ -163,7 +163,7 @@ copies: ${DESTDIR}${INCLUDEDIR}/$i .endfor cd ${.CURDIR}/../sys/dev/acpica; \ - ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 acpiio.h \ + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 acpi_hpet.h acpiio.h \ ${DESTDIR}${INCLUDEDIR}/dev/acpica cd ${.CURDIR}/../sys/dev/bktr; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ioctl_*.h \ Index: sys/dev/acpica/acpi_hpet.c =================================================================== --- sys/dev/acpica/acpi_hpet.c (revision 221997) +++ sys/dev/acpica/acpi_hpet.c (working copy) @@ -36,8 +36,11 @@ __FBSDID("$FreeBSD$"); #endif #include #include +#include +#include #include #include +#include #include #include #include @@ -70,6 +73,7 @@ ACPI_MODULE_NAME("HPET") struct hpet_softc { device_t dev; + struct cdev *cdev; int mem_rid; int intr_rid; int irq; @@ -106,11 +110,54 @@ struct hpet_softc { int num_timers; }; +static d_open_t hpet_open; +static d_mmap_t hpet_mmap; + static u_int hpet_get_timecount(struct timecounter *tc); static void hpet_test(struct hpet_softc *sc); +static struct cdevsw hpet_cdevsw = { + .d_version = D_VERSION, + .d_open = hpet_open, + .d_mmap = hpet_mmap, + .d_name = "hpet", +}; + static char *hpet_ids[] = { "PNP0103", NULL }; +static int +hpet_open(struct cdev *dev __unused, int oflag, int devtype __unused, + struct thread *td) +{ + struct hpet_softc *sc; + + sc = devclass_get_softc(hpet_devclass, 0); + if (sc == NULL) + return (ENXIO); + if ((oflag & (O_CREAT | O_APPEND | O_TRUNC)) != 0) + return (EACCES); + if ((oflag & O_ACCMODE) != O_RDONLY) + return (securelevel_gt(td->td_ucred, 0)); + return (0); +} + +static int +hpet_mmap(struct cdev *dev __unused, vm_ooffset_t offset, vm_paddr_t *paddr, + int nprot, vm_memattr_t *memattr __unused) +{ + struct hpet_softc *sc; + + sc = devclass_get_softc(hpet_devclass, 0); + if (sc == NULL) + return (ENODEV); + if (offset < 0 || offset >= rman_get_size(sc->mem_res)) + return (EINVAL); + if ((nprot & PROT_EXEC) != 0) + return (EACCES); + *paddr = rman_get_start(sc->mem_res) + offset; + return (0); +} + static u_int hpet_get_timecount(struct timecounter *tc) { @@ -480,6 +527,9 @@ hpet_attach(device_t dev) sc->tc.tc_frequency = sc->freq; sc->tc.tc_priv = sc; tc_init(&sc->tc); + /* Create /dev/hpet. */ + sc->cdev = make_dev(&hpet_cdevsw, device_get_unit(dev), + UID_ROOT, GID_WHEEL, 0644, "hpet"); } /* If not disabled - setup and announce event timers. */ if (resource_int_value(device_get_name(dev), device_get_unit(dev), @@ -697,8 +747,15 @@ hpet_attach(device_t dev) static int hpet_detach(device_t dev) { + struct hpet_softc *sc; + ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); + if (device_get_unit(dev) == 0) { + sc = device_get_softc(dev); + destroy_dev(sc->cdev); + } + /* XXX Without a tc_remove() function, we can't detach. */ return (EBUSY); }