Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/iicbus/iiconf.c
| Show All 36 Lines | |||||
| #include <sys/mutex.h> | #include <sys/mutex.h> | ||||
| #include <sys/bus.h> | #include <sys/bus.h> | ||||
| #include <dev/iicbus/iiconf.h> | #include <dev/iicbus/iiconf.h> | ||||
| #include <dev/iicbus/iicbus.h> | #include <dev/iicbus/iicbus.h> | ||||
| #include "iicbus_if.h" | #include "iicbus_if.h" | ||||
| /* | /* | ||||
| * Encode a system errno value into the IIC_Exxxxx space by setting the | |||||
| * IIC_ERRNO marker bit, so that iic2errno() can turn it back into a plain | |||||
| * system errno value later. This lets controller- and bus-layer code get | |||||
| * important system errno values (such as EINTR/ERESTART) back to the caller. | |||||
| */ | |||||
| int | |||||
| errno2iic(int errno) | |||||
| { | |||||
| return ((errno == 0) ? 0 : errno | IIC_ERRNO); | |||||
| } | |||||
| /* | |||||
| * Translate IIC_Exxxxx status values to vaguely-equivelent errno values. | * Translate IIC_Exxxxx status values to vaguely-equivelent errno values. | ||||
| */ | */ | ||||
| int | int | ||||
| iic2errno(int iic_status) | iic2errno(int iic_status) | ||||
| { | { | ||||
| switch (iic_status) { | switch (iic_status) { | ||||
| case IIC_NOERR: return (0); | case IIC_NOERR: return (0); | ||||
| case IIC_EBUSERR: return (EALREADY); | case IIC_EBUSERR: return (EALREADY); | ||||
| case IIC_ENOACK: return (EIO); | case IIC_ENOACK: return (EIO); | ||||
| case IIC_ETIMEOUT: return (ETIMEDOUT); | case IIC_ETIMEOUT: return (ETIMEDOUT); | ||||
| case IIC_EBUSBSY: return (EWOULDBLOCK); | case IIC_EBUSBSY: return (EWOULDBLOCK); | ||||
| case IIC_ESTATUS: return (EPROTO); | case IIC_ESTATUS: return (EPROTO); | ||||
| case IIC_EUNDERFLOW: return (EIO); | case IIC_EUNDERFLOW: return (EIO); | ||||
| case IIC_EOVERFLOW: return (EOVERFLOW); | case IIC_EOVERFLOW: return (EOVERFLOW); | ||||
| case IIC_ENOTSUPP: return (EOPNOTSUPP); | case IIC_ENOTSUPP: return (EOPNOTSUPP); | ||||
| case IIC_ENOADDR: return (EADDRNOTAVAIL); | case IIC_ENOADDR: return (EADDRNOTAVAIL); | ||||
| case IIC_ERESOURCE: return (ENOMEM); | case IIC_ERESOURCE: return (ENOMEM); | ||||
| default: return (EIO); | default: | ||||
| /* | |||||
| * If the high bit is set, that means it's a system errno value | |||||
| * that was encoded into the IIC_Exxxxxx space by setting the | |||||
| * IIC_ERRNO marker bit. If lots of high-order bits are set, | |||||
| * then it's one of the negative pseudo-errors such as ERESTART | |||||
| * and we return it as-is. Otherwise it's a plain "small | |||||
| * positive integer" errno, so just remove the IIC_ERRNO marker | |||||
| * bit. If it's some unknown number without the high bit set, | |||||
| * there isn't much we can do except call it an I/O error. | |||||
| */ | |||||
| if ((iic_status & IIC_ERRNO) == 0) | |||||
| return (EIO); | |||||
| if ((iic_status & 0xFFFF0000) != 0) | |||||
| return (iic_status); | |||||
| return (iic_status & ~IIC_ERRNO); | |||||
| } | } | ||||
| } | } | ||||
| /* | /* | ||||
| * iicbus_intr() | * iicbus_intr() | ||||
| */ | */ | ||||
| void | void | ||||
| iicbus_intr(device_t bus, int event, char *buf) | iicbus_intr(device_t bus, int event, char *buf) | ||||
| Show All 21 Lines | iicbus_poll(struct iicbus_softc *sc, int how) | ||||
| case IIC_WAIT | IIC_NOINTR: | case IIC_WAIT | IIC_NOINTR: | ||||
| error = mtx_sleep(sc, &sc->lock, IICPRI, "iicreq", 0); | error = mtx_sleep(sc, &sc->lock, IICPRI, "iicreq", 0); | ||||
| break; | break; | ||||
| default: | default: | ||||
| return (IIC_EBUSBSY); | return (IIC_EBUSBSY); | ||||
| } | } | ||||
| return (error); | return (errno2iic(error)); | ||||
| } | } | ||||
| /* | /* | ||||
| * iicbus_request_bus() | * iicbus_request_bus() | ||||
| * | * | ||||
| * Allocate the device to perform transfers. | * Allocate the device to perform transfers. | ||||
| * | * | ||||
| * how : IIC_WAIT or IIC_DONTWAIT | * how : IIC_WAIT or IIC_DONTWAIT | ||||
| ▲ Show 20 Lines • Show All 429 Lines • Show Last 20 Lines | |||||