static int intsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) { struct intsmb_softc *sc = device_get_softc(dev); int error, i; if (count > SMBBLOCKTRANS_MAX || count == 0) return (SMB_EINVAL); INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } /* Reset internal array index. */ bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); for (i = 0; i < count; i++) bus_write_1(sc->io_res, PIIX4_SMBBLKDAT, buf[i]); bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, count); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BLOCK, 0); error = intsmb_stop(sc); INTSMB_UNLOCK(sc); return (error); }
static int intsmb_recvb(device_t dev, u_char slave, char *byte) { struct intsmb_softc *sc = device_get_softc(dev); int error; INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 0); error = intsmb_stop(sc); if (error == 0) { #ifdef RECV_IS_IN_CMD /* * Linux SMBus stuff also troubles * Because Intel's datasheet does not make clear. */ *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTCMD); #else *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); #endif } INTSMB_UNLOCK(sc); return (error); }
/* * Data sheet claims that it implements all function, but also claims * that it implements 7 function and not mention PCALL. So I don't know * whether it will work. */ static int intsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) { #ifdef PROCCALL_TEST struct intsmb_softc *sc = device_get_softc(dev); int error; INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, sdata & 0xff); bus_write_1(sc->io_res, PIIX4_SMBHSTDAT1, (sdata & 0xff) >> 8); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0); error = intsmb_stop(sc); if (error == 0) { *rdata = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); *rdata |= bus_read_1(sc->io_res, PIIX4_SMBHSTDAT1) << 8; } INTSMB_UNLOCK(sc); return (error); #else return (SMB_ENOTSUPP); #endif }
static int intsmb_quick(device_t dev, u_char slave, int how) { struct intsmb_softc *sc = device_get_softc(dev); int error; u_char data; data = slave; /* Quick command is part of Address, I think. */ switch(how) { case SMB_QWRITE: data &= ~LSB; break; case SMB_QREAD: data |= LSB; break; default: return (SMB_EINVAL); } INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } bus_write_1(sc->io_res, PIIX4_SMBHSTADD, data); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_QUICK, 0); error = intsmb_stop(sc); INTSMB_UNLOCK(sc); return (error); }
static int intsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) { struct intsmb_softc *sc = device_get_softc(dev); int error, i; u_char data, nread; INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } /* Reset internal array index. */ bus_read_1(sc->io_res, PIIX4_SMBHSTCNT); bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BLOCK, 0); error = intsmb_stop(sc); if (error == 0) { nread = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); if (nread != 0 && nread <= SMBBLOCKTRANS_MAX) { *count = nread; for (i = 0; i < nread; i++) data = bus_read_1(sc->io_res, PIIX4_SMBBLKDAT); } else error = SMB_EBUSERR; } INTSMB_UNLOCK(sc); return (error); }
static int intsmb_sendb(device_t dev, u_char slave, char byte) { struct intsmb_softc *sc = device_get_softc(dev); int error; INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, byte); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 0); error = intsmb_stop(sc); INTSMB_UNLOCK(sc); return (error); }
static int intsmb_readb(device_t dev, u_char slave, char cmd, char *byte) { struct intsmb_softc *sc = device_get_softc(dev); int error; INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BDATA, 0); error = intsmb_stop(sc); if (error == 0) *byte = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); INTSMB_UNLOCK(sc); return (error); }
static int intsmb_writew(device_t dev, u_char slave, char cmd, short word) { struct intsmb_softc *sc = device_get_softc(dev); int error; INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave & ~LSB); bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); bus_write_1(sc->io_res, PIIX4_SMBHSTDAT0, word & 0xff); bus_write_1(sc->io_res, PIIX4_SMBHSTDAT1, (word >> 8) & 0xff); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0); error = intsmb_stop(sc); INTSMB_UNLOCK(sc); return (error); }
static void intsmb_alrintr(struct intsmb_softc *sc) { int slvcnt; #ifdef ENABLE_ALART int error; uint8_t addr; #endif /* Stop generating INTR from ALART. */ slvcnt = bus_read_1(sc->io_res, PIIX4_SMBSLVCNT); #ifdef ENABLE_ALART bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, slvcnt & ~PIIX4_SMBSLVCNT_ALTEN); #endif DELAY(5); /* Ask bus who asserted it and then ask it what's the matter. */ #ifdef ENABLE_ALART error = intsmb_free(sc); if (error) return; bus_write_1(sc->io_res, PIIX4_SMBHSTADD, SMBALTRESP | LSB); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_BYTE, 1); error = intsmb_stop_poll(sc); if (error) device_printf(sc->dev, "ALART: ERROR\n"); else { addr = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); device_printf(sc->dev, "ALART_RESPONSE: 0x%x\n", addr); } /* Re-enable INTR from ALART. */ bus_write_1(sc->io_res, PIIX4_SMBSLVCNT, slvcnt | PIIX4_SMBSLVCNT_ALTEN); DELAY(5); #endif }
static int intsmb_readw(device_t dev, u_char slave, char cmd, short *word) { struct intsmb_softc *sc = device_get_softc(dev); int error; INTSMB_LOCK(sc); error = intsmb_free(sc); if (error) { INTSMB_UNLOCK(sc); return (error); } bus_write_1(sc->io_res, PIIX4_SMBHSTADD, slave | LSB); bus_write_1(sc->io_res, PIIX4_SMBHSTCMD, cmd); intsmb_start(sc, PIIX4_SMBHSTCNT_PROT_WDATA, 0); error = intsmb_stop(sc); if (error == 0) { *word = bus_read_1(sc->io_res, PIIX4_SMBHSTDAT0); *word |= bus_read_1(sc->io_res, PIIX4_SMBHSTDAT1) << 8; } INTSMB_UNLOCK(sc); return (error); }