static int alpm_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) { struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev); u_char data, len, i; int error; if (*count < 1 || *count > 32) return (SMB_EINVAL); ALPM_LOCK(sc); alpm_clear(sc); if (!alpm_idle(sc)) { ALPM_UNLOCK(sc); return (SMB_EBUSY); } ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB); /* set the cmd and reset the * 32-byte long internal buffer */ ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR); ALPM_SMBOUTB(sc, SMBHCMD, cmd); ALPM_SMBOUTB(sc, SMBSTART, 0xff); if ((error = alpm_wait(sc)) != SMB_ENOERR) goto error; len = ALPM_SMBINB(sc, SMBHDATA); /* read the 32-byte internal buffer */ for (i = 0; i < len; i++) { data = ALPM_SMBINB(sc, SMBHBLOCK); if (i < *count) buf[i] = data; DELAY(2); } *count = len; error: ALPM_DEBUG(kprintf("alpm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error)); ALPM_UNLOCK(sc); return (error); }
static int alpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) { struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev); u_char i; int error; if (count < 1 || count > 32) return (SMB_EINVAL); ALPM_LOCK(sc); alpm_clear(sc); if(!alpm_idle(sc)) { ALPM_UNLOCK(sc); return (SMB_EBUSY); } ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB); /* set the cmd and reset the * 32-byte long internal buffer */ ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR); ALPM_SMBOUTB(sc, SMBHDATA, count); /* fill the 32-byte internal buffer */ for (i = 0; i < count; i++) { ALPM_SMBOUTB(sc, SMBHBLOCK, buf[i]); DELAY(2); } ALPM_SMBOUTB(sc, SMBHCMD, cmd); ALPM_SMBOUTB(sc, SMBSTART, 0xff); error = alpm_wait(sc); ALPM_DEBUG(printf("alpm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error)); ALPM_UNLOCK(sc); return (error); }
static int alpm_quick(device_t dev, u_char slave, int how) { struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev); int error; ALPM_LOCK(sc); alpm_clear(sc); if (!alpm_idle(sc)) { ALPM_UNLOCK(sc); return (EBUSY); } switch (how) { case SMB_QWRITE: ALPM_DEBUG(printf("alpm: QWRITE to 0x%x", slave)); ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB); break; case SMB_QREAD: ALPM_DEBUG(printf("alpm: QREAD to 0x%x", slave)); ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB); break; default: panic("%s: unknown QUICK command (%x)!", __func__, how); } ALPM_SMBOUTB(sc, SMBCMD, SMBQUICK); ALPM_SMBOUTB(sc, SMBSTART, 0xff); error = alpm_wait(sc); ALPM_DEBUG(printf(", error=0x%x\n", error)); ALPM_UNLOCK(sc); return (error); }