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 |