From f81520ed84ebc2b7f80247aea361fe0907138edc Mon Sep 17 00:00:00 2001 From: "Constantine A. Murenin" Date: Mon, 8 Mar 2010 05:26:58 -0500 Subject: [PATCH] wbsio(4): convert to Newbus and DragonFly -- welcome wbsio(4)! * New wbsio(4) driver for Winbond Super I/O attachment of lm(4) on any port. --- share/man/man4/Makefile | 1 + share/man/man4/isa.4 | 2 + share/man/man4/lm.4 | 8 +- share/man/man4/wbsio.4 | 16 ++- sys/conf/files | 1 + sys/config/GENERIC | 3 + sys/config/LINT | 3 + sys/config/X86_64_GENERIC | 3 + sys/dev/powermng/wbsio/Makefile | 5 + sys/dev/powermng/wbsio/wbsio.c | 228 +++++++++++++++++++------------- 10 files changed, 172 insertions(+), 98 deletions(-) create mode 100644 sys/dev/powermng/wbsio/Makefile diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 749a1b0f5b..a67d8363fc 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -334,6 +334,7 @@ MAN= aac.4 \ vr.4 \ watchdog.4 \ wb.4 \ + wbsio.4 \ wi.4 \ wlan.4 \ wlan_acl.4 \ diff --git a/share/man/man4/isa.4 b/share/man/man4/isa.4 index 28f5989c55..709358f331 100644 --- a/share/man/man4/isa.4 +++ b/share/man/man4/isa.4 @@ -159,6 +159,8 @@ ITE IT8705F/IT8712F/IT8716F/IT8718F/IT8726F and SiS SiS950 temperature, voltage, and fan sensor with watchdog timer .It Xr lm 4 National Semiconductor LM78/79/81 temperature, voltage, and fan sensor +.It Xr wbsio 4 +Winbond LPC Super I/O .El .Ss Miscellaneous devices .Bl -tag -width 12n -offset indent -compact diff --git a/share/man/man4/lm.4 b/share/man/man4/lm.4 index 45874b8d81..0366e3afed 100644 --- a/share/man/man4/lm.4 +++ b/share/man/man4/lm.4 @@ -36,7 +36,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd August 19, 2007 +.Dd March 8, 2010 .Dt LM 4 .Os .Sh NAME @@ -46,6 +46,10 @@ .Cd "device lm0 at isa? port 0x290" .Cd "device lm1 at isa? port 0x280" .Cd "device lm2 at isa? port 0x310" +.Pp +.Cd "device wbsio0 at isa? port 0x2e" +.Cd "device wbsio1 at isa? port 0x4e" +.Cd "device lm#3 at wbsio?" .Sh DESCRIPTION The .Nm @@ -85,6 +89,8 @@ ASUS AS99127F .Sh SEE ALSO .Xr systat 1 , .Xr sysctl 3 , +.Xr isa 4 , +.Xr wbsio 4 , .Xr sensorsd 8 , .Xr sysctl 8 .Sh HISTORY diff --git a/share/man/man4/wbsio.4 b/share/man/man4/wbsio.4 index d5207ae182..f4e9bb0fb5 100644 --- a/share/man/man4/wbsio.4 +++ b/share/man/man4/wbsio.4 @@ -15,16 +15,16 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd February 16, 2010 +.Dd March 8, 2010 .Dt WBSIO 4 .Os .Sh NAME .Nm wbsio .Nd Winbond LPC Super I/O .Sh SYNOPSIS -.Cd "wbsio* at isa? port 0x2e" -.Cd "wbsio* at isa? port 0x4e" -.Cd "lm* at wbsio?" +.Cd "device wbsio0 at isa? port 0x2e" +.Cd "device wbsio1 at isa? port 0x4e" +.Cd "device lm" .Sh DESCRIPTION The .Nm @@ -46,6 +46,9 @@ driver first appeared in .Nx support was added in .Nx 6.0 . +.Dx +support was added in +.Dx 2.5 . .Sh AUTHORS .An -nosplit The @@ -54,5 +57,8 @@ driver was written by .An Mark Kettenis Aq kettenis@openbsd.org . It was adapted to .Nx +and +.Dx by -.An Constantine A. Murenin Aq cnst@NetBSD.org . +.An Constantine A. Murenin , +University of Waterloo. diff --git a/sys/conf/files b/sys/conf/files index bed6e9f721..7502c5fde4 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1693,6 +1693,7 @@ dev/powermng/aps/aps.c optional aps isa dev/powermng/it/it.c optional it isa dev/powermng/lm/lm78.c optional lm isa dev/powermng/lm/lm78_isa.c optional lm isa +dev/powermng/wbsio/wbsio.c optional wbsio isa emulation/43bsd/43bsd_socket.c optional compat_43 emulation/43bsd/43bsd_stats.c optional compat_43 emulation/43bsd/43bsd_file.c optional compat_43 diff --git a/sys/config/GENERIC b/sys/config/GENERIC index 66b9800915..def0d867ba 100644 --- a/sys/config/GENERIC +++ b/sys/config/GENERIC @@ -195,6 +195,9 @@ device it0 at isa? port 0x290 device it1 at isa? port 0xc00 device it2 at isa? port 0xd00 device it3 at isa? port 0x228 +device wbsio0 at isa? port 0x2e +device wbsio1 at isa? port 0x4e +device lm#3 at wbsio? # PCCARD (PCMCIA) support device pccard diff --git a/sys/config/LINT b/sys/config/LINT index 3a15ccc356..8b6307056a 100644 --- a/sys/config/LINT +++ b/sys/config/LINT @@ -2108,6 +2108,9 @@ device it2 at isa? port 0xd00 device it3 at isa? port 0x228 device nsclpcsio0 at isa? port 0x2e device nsclpcsio1 at isa? port 0x4e +device wbsio0 at isa? port 0x2e +device wbsio1 at isa? port 0x4e +device lm#3 at wbsio? #--------------------------------------------------------------------------- # ISDN4BSD diff --git a/sys/config/X86_64_GENERIC b/sys/config/X86_64_GENERIC index 887e9d1308..8e3748f93d 100644 --- a/sys/config/X86_64_GENERIC +++ b/sys/config/X86_64_GENERIC @@ -170,6 +170,9 @@ device it0 at isa? port 0x290 device it1 at isa? port 0xc00 device it2 at isa? port 0xd00 device it3 at isa? port 0x228 +device wbsio0 at isa? port 0x2e +device wbsio1 at isa? port 0x4e +device lm#3 at wbsio? # PCCARD (PCMCIA) support device pccard diff --git a/sys/dev/powermng/wbsio/Makefile b/sys/dev/powermng/wbsio/Makefile new file mode 100644 index 0000000000..482d37d533 --- /dev/null +++ b/sys/dev/powermng/wbsio/Makefile @@ -0,0 +1,5 @@ +KMOD= wbsio +SRCS= ${KMOD}.c +SRCS+= isa_if.h bus_if.h device_if.h + +.include diff --git a/sys/dev/powermng/wbsio/wbsio.c b/sys/dev/powermng/wbsio/wbsio.c index 9dd159f755..5b051cb15e 100644 --- a/sys/dev/powermng/wbsio/wbsio.c +++ b/sys/dev/powermng/wbsio/wbsio.c @@ -2,6 +2,7 @@ /* $OpenBSD: wbsio.c,v 1.5 2009/03/29 21:53:52 sthen Exp $ */ /* * Copyright (c) 2008 Mark Kettenis + * Copyright (c) 2010 Constantine A. Murenin * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,14 +22,13 @@ */ #include -#include +#include #include +#include +#include #include -#include - -#include -#include +#include /* ISA bus registers */ #define WBSIO_INDEX 0x00 /* Configuration Index Register */ @@ -60,18 +60,37 @@ #define WBSIO_HM_ADDR_LSB 0x61 /* Address [7:0] */ struct wbsio_softc { - struct device sc_dev; + struct device *sc_dev; + + struct resource *sc_iores; + int sc_iorid; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; }; -int wbsio_probe(device_t, cfdata_t, void *); -void wbsio_attach(device_t, device_t, void *); -int wbsio_print(void *, const char *); +static int wbsio_probe(struct device *); +static int wbsio_attach(struct device *); +static int wbsio_detach(struct device *); + +static device_method_t wbsio_methods[] = { + DEVMETHOD(device_probe, wbsio_probe), + DEVMETHOD(device_attach, wbsio_attach), + DEVMETHOD(device_detach, wbsio_detach), + + { NULL, NULL} +}; + +static driver_t wbsio_driver = { + "wbsio", + wbsio_methods, + sizeof(struct wbsio_softc) +}; + +static devclass_t wbsio_devclass; + +DRIVER_MODULE(wbsio, isa, wbsio_driver, wbsio_devclass, NULL, NULL); -CFATTACH_DECL_NEW(wbsio, sizeof(struct wbsio_softc), - wbsio_probe, wbsio_attach, NULL, NULL); static __inline void wbsio_conf_enable(bus_space_tag_t iot, bus_space_handle_t ioh) @@ -101,75 +120,36 @@ wbsio_conf_write(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t index, bus_space_write_1(iot, ioh, WBSIO_DATA, data); } -int -wbsio_probe(device_t parent, cfdata_t match, void *aux) +static int +wbsio_probe(struct device *dev) { - struct isa_attach_args *ia = aux; + struct resource *iores; + int iorid = 0; bus_space_tag_t iot; bus_space_handle_t ioh; - u_int8_t reg; - - /* Must supply an address */ - if (ia->ia_nio < 1) - return 0; + uint8_t reg_id, reg_rev; + const char *desc = NULL; + char fulldesc[64]; - if (ISA_DIRECT_CONFIG(ia)) - return 0; + /* Match by device ID */ - if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) - return 0; + iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &iorid, + 0ul, ~0ul, WBSIO_IOSIZE, + RF_ACTIVE); + if (iores == NULL) + return ENXIO; + iot = rman_get_bustag(iores); + ioh = rman_get_bushandle(iores); - /* Match by device ID */ - iot = ia->ia_iot; - if (bus_space_map(iot, ia->ia_io[0].ir_addr, WBSIO_IOSIZE, 0, &ioh)) - return 0; wbsio_conf_enable(iot, ioh); - reg = wbsio_conf_read(iot, ioh, WBSIO_ID); - aprint_debug("wbsio_probe: id 0x%02x\n", reg); + /* Read device ID */ + reg_id = wbsio_conf_read(iot, ioh, WBSIO_ID); + /* Read device revision */ + reg_rev = wbsio_conf_read(iot, ioh, WBSIO_REV); wbsio_conf_disable(iot, ioh); - bus_space_unmap(iot, ioh, WBSIO_IOSIZE); - switch (reg) { - case WBSIO_ID_W83627HF: - case WBSIO_ID_W83627THF: - case WBSIO_ID_W83627EHF: - case WBSIO_ID_W83627DHG: - case WBSIO_ID_W83637HF: - case WBSIO_ID_W83697HF: - ia->ia_nio = 1; - ia->ia_io[0].ir_size = WBSIO_IOSIZE; - ia->ia_niomem = 0; - ia->ia_nirq = 0; - ia->ia_ndrq = 0; - return 1; - } - - return 0; -} + bus_release_resource(dev, SYS_RES_IOPORT, iorid, iores); -void -wbsio_attach(device_t parent, device_t self, void *aux) -{ - struct wbsio_softc *sc = (void *)self; - struct isa_attach_args *ia = aux; - struct isa_attach_args nia; - const char *desc = NULL; - u_int8_t reg, reg0, reg1; - u_int16_t iobase; - - /* Map ISA I/O space */ - sc->sc_iot = ia->ia_iot; - if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, - WBSIO_IOSIZE, 0, &sc->sc_ioh)) { - aprint_error(": can't map i/o space\n"); - return; - } - - /* Enter configuration mode */ - wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); - - /* Read device ID */ - reg = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_ID); - switch (reg) { + switch (reg_id) { case WBSIO_ID_W83627HF: desc = "W83627HF"; break; @@ -190,11 +170,39 @@ wbsio_attach(device_t parent, device_t self, void *aux) break; } - /* Read device revision */ - reg = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_REV); + if (desc == NULL) + return ENXIO; - aprint_naive("\n"); - aprint_normal(": Winbond LPC Super I/O %s rev 0x%02x\n", desc, reg); + ksnprintf(fulldesc, sizeof(fulldesc), + "Winbond LPC Super I/O %s rev 0x%02x", desc, reg_rev); + device_set_desc_copy(dev, fulldesc); + return 0; +} + +static int +wbsio_attach(struct device *dev) +{ + struct wbsio_softc *sc = device_get_softc(dev); + uint8_t reg0, reg1; + uint16_t iobase; + struct device *parent = device_get_parent(dev); + struct device *child; + struct devclass *c_dc; + int c_maxunit; + + /* Map ISA I/O space */ + sc->sc_iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->sc_iorid, + 0ul, ~0ul, WBSIO_IOSIZE, + RF_ACTIVE); + if (sc->sc_iores == NULL) { + device_printf(dev, "can't map i/o space\n"); + return ENXIO; + } + sc->sc_iot = rman_get_bustag(sc->sc_iores); + sc->sc_ioh = rman_get_bushandle(sc->sc_iores); + + /* Enter configuration mode */ + wbsio_conf_enable(sc->sc_iot, sc->sc_ioh); /* Select HM logical device */ wbsio_conf_write(sc->sc_iot, sc->sc_ioh, WBSIO_LDN, WBSIO_LDN_HM); @@ -208,29 +216,65 @@ wbsio_attach(device_t parent, device_t self, void *aux) reg0 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_HM_ADDR_LSB); reg1 = wbsio_conf_read(sc->sc_iot, sc->sc_ioh, WBSIO_HM_ADDR_MSB); iobase = (reg1 << 8) | (reg0 & ~0x7); + device_printf(dev, "hardware monitor iobase is 0x%x\n", iobase); /* Escape from configuration mode */ wbsio_conf_disable(sc->sc_iot, sc->sc_ioh); - if (iobase == 0) - return; + if (iobase == 0) { + device_printf(dev, "no hardware monitor configured\n"); + return 0; + } - nia = *ia; - nia.ia_io[0].ir_addr = iobase; - config_found(self, &nia, wbsio_print); + child = NULL; + c_dc = devclass_find("lm"); + if (c_dc == NULL) { + device_printf(dev, "lm devclass not found\n"); + return ENXIO; + } + c_maxunit = devclass_get_maxunit(c_dc); + for (int u = 0; u < c_maxunit; u++) { + child = devclass_get_device(c_dc, u); + if (child == NULL) + continue; + if (isa_get_port(child) == iobase) { + if (device_is_attached(child)) { + device_printf(dev, + "%s is already attached at 0x%x\n", + device_get_nameunit(child), iobase); + return 0; + } + break; + } + if (device_is_attached(child)) + continue; + device_printf(dev, + "found unused %s at 0x%x with state %i, reusing at 0x%x\n", + device_get_nameunit(child), isa_get_port(child), + device_get_state(child), iobase); + break; + } + if (child == NULL) + child = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP, + "lm", -1); +// child = BUS_ADD_CHILD(parent, parent, ISA_ORDER_PNP, +// "lm", 3 + device_get_unit(dev)); + if (child == NULL) { + device_printf(dev, "cannot add child\n"); + return ENXIO; + } + if (bus_set_resource(child, SYS_RES_IOPORT, 0, iobase, 8)) { + device_printf(dev, "cannot set resource\n"); + return ENXIO; + } + return device_probe_and_attach(child); } -int -wbsio_print(void *aux, const char *pnp) +static int +wbsio_detach(struct device *dev) { - struct isa_attach_args *ia = aux; - - if (pnp) - aprint_normal("%s", pnp); - if (ia->ia_io[0].ir_size) - aprint_normal(" port 0x%x", ia->ia_io[0].ir_addr); - if (ia->ia_io[0].ir_size > 1) - aprint_normal("-0x%x", ia->ia_io[0].ir_addr + - ia->ia_io[0].ir_size - 1); - return (UNCONF); + struct wbsio_softc *sc = device_get_softc(dev); + + return bus_release_resource(dev, SYS_RES_IOPORT, + sc->sc_iorid, sc->sc_iores); } -- 2.41.0