Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161412882
D8170.id21132.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D8170.id21132.diff
View Options
Index: sys/dev/iicbus/iicsmb.c
===================================================================
--- sys/dev/iicbus/iicsmb.c
+++ sys/dev/iicbus/iicsmb.c
@@ -131,8 +131,6 @@
sizeof(struct iicsmb_softc),
};
-#define IICBUS_TIMEOUT 100 /* us */
-
static void
iicsmb_identify(driver_t *driver, device_t parent)
{
@@ -276,237 +274,213 @@
}
static int
+iic2smb_error(int error)
+{
+ switch (error) {
+ case IIC_NOERR:
+ return (SMB_ENOERR);
+ case IIC_EBUSERR:
+ return (SMB_EBUSERR);
+ case IIC_ENOACK:
+ return (SMB_ENOACK);
+ case IIC_ETIMEOUT:
+ return (SMB_ETIMEOUT);
+ case IIC_EBUSBSY:
+ return (SMB_EBUSY);
+ case IIC_ESTATUS:
+ return (SMB_EBUSERR);
+ case IIC_EUNDERFLOW:
+ return (SMB_EBUSERR);
+ case IIC_EOVERFLOW:
+ return (SMB_EBUSERR);
+ case IIC_ENOTSUPP:
+ return (SMB_ENOTSUPP);
+ case IIC_ENOADDR:
+ return (SMB_EBUSERR);
+ case IIC_ERESOURCE:
+ return (SMB_EBUSERR);
+ default:
+ return (SMB_EBUSERR);
+ }
+}
+
+#define TRANSFER_MSGS(dev, msgs) iicbus_transfer(dev, msgs, nitems(msgs))
+
+static int
iicsmb_quick(device_t dev, u_char slave, int how)
{
- device_t parent = device_get_parent(dev);
+ struct iic_msg msgs[] = {
+ { slave, how == SMB_QWRITE ? IIC_M_WR : IIC_M_RD, 0, NULL },
+ };
int error;
switch (how) {
case SMB_QWRITE:
- error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT);
- break;
-
case SMB_QREAD:
- error = iicbus_start(parent, slave | LSB, IICBUS_TIMEOUT);
break;
-
default:
- error = EINVAL;
- break;
+ return (SMB_EINVAL);
}
- if (!error)
- error = iicbus_stop(parent);
-
- return (error);
+ error = TRANSFER_MSGS(dev, msgs);
+ return (iic2smb_error(error));
}
static int
iicsmb_sendb(device_t dev, u_char slave, char byte)
{
- device_t parent = device_get_parent(dev);
- int error, sent;
-
- error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT);
-
- if (!error) {
- error = iicbus_write(parent, &byte, 1, &sent, IICBUS_TIMEOUT);
-
- iicbus_stop(parent);
- }
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_WR, 1, &byte },
+ };
+ int error;
- return (error);
+ error = TRANSFER_MSGS(dev, msgs);
+ return (iic2smb_error(error));
}
static int
iicsmb_recvb(device_t dev, u_char slave, char *byte)
{
- device_t parent = device_get_parent(dev);
- int error, read;
-
- error = iicbus_start(parent, slave | LSB, 0);
-
- if (!error) {
- error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, IICBUS_TIMEOUT);
-
- iicbus_stop(parent);
- }
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_RD, 1, byte },
+ };
+ int error;
- return (error);
+ error = TRANSFER_MSGS(dev, msgs);
+ return (iic2smb_error(error));
}
static int
iicsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
{
- device_t parent = device_get_parent(dev);
- int error, sent;
-
- error = iicbus_start(parent, slave & ~LSB, 0);
-
- if (!error) {
- if (!(error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
- error = iicbus_write(parent, &byte, 1, &sent, IICBUS_TIMEOUT);
-
- iicbus_stop(parent);
- }
+ uint8_t bytes[] = { cmd, byte };
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_WR, nitems(bytes), bytes },
+ };
+ int error;
- return (error);
+ error = TRANSFER_MSGS(dev, msgs);
+ return (iic2smb_error(error));
}
static int
iicsmb_writew(device_t dev, u_char slave, char cmd, short word)
{
- device_t parent = device_get_parent(dev);
- int error, sent;
-
- char low = (char)(word & 0xff);
- char high = (char)((word & 0xff00) >> 8);
-
- error = iicbus_start(parent, slave & ~LSB, 0);
-
- if (!error) {
- if (!(error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
- if (!(error = iicbus_write(parent, &low, 1, &sent, IICBUS_TIMEOUT)))
- error = iicbus_write(parent, &high, 1, &sent, IICBUS_TIMEOUT);
-
- iicbus_stop(parent);
- }
+ uint8_t bytes[] = { cmd, word & 0xff, word >> 8 };
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_WR, nitems(bytes), bytes },
+ };
+ int error;
- return (error);
+ error = TRANSFER_MSGS(dev, msgs);
+ return (iic2smb_error(error));
}
static int
iicsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
{
- device_t parent = device_get_parent(dev);
- int error, sent, read;
-
- if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
- return (error);
-
- if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
- goto error;
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_WR | IIC_M_NOSTOP, 1, &cmd },
+ { slave, IIC_M_RD, 1, byte },
+ };
+ int error;
-error:
- iicbus_stop(parent);
- return (error);
+ error = TRANSFER_MSGS(dev, msgs);
+ return (iic2smb_error(error));
}
-#define BUF2SHORT(low,high) \
- ((short)(((high) & 0xff) << 8) | (short)((low) & 0xff))
-
static int
iicsmb_readw(device_t dev, u_char slave, char cmd, short *word)
{
- device_t parent = device_get_parent(dev);
- int error, sent, read;
- char buf[2];
-
- if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
- return (error);
-
- if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
- goto error;
-
- /* first, receive low, then high byte */
- *word = BUF2SHORT(buf[0], buf[1]);
+ uint8_t buf[2];
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_WR | IIC_M_NOSTOP, 1, &cmd },
+ { slave, IIC_M_RD, nitems(buf), buf },
+ };
+ int error;
-error:
- iicbus_stop(parent);
- return (error);
+ error = TRANSFER_MSGS(dev, msgs);
+ if (error == 0)
+ *word = ((uint16_t)buf[1] << 8) | buf[0];
+ return (iic2smb_error(error));
}
static int
iicsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata)
{
- device_t parent = device_get_parent(dev);
- int error, sent, read;
- char buf[2];
-
- if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
- return (error);
-
- if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
- goto error;
-
- /* first, send low, then high byte */
- buf[0] = (char)(sdata & 0xff);
- buf[1] = (char)((sdata & 0xff00) >> 8);
-
- if ((error = iicbus_write(parent, buf, 2, &sent, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, IICBUS_TIMEOUT)))
- goto error;
-
- /* first, receive low, then high byte */
- *rdata = BUF2SHORT(buf[0], buf[1]);
+ uint8_t in[3] = { cmd, sdata & 0xff, sdata >> 8 };
+ uint8_t out[2];
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_WR | IIC_M_NOSTOP, nitems(in), in },
+ { slave, IIC_M_RD, nitems(out), out },
+ };
+ int error;
-error:
- iicbus_stop(parent);
- return (error);
+ error = TRANSFER_MSGS(dev, msgs);
+ if (error == 0)
+ *rdata = ((uint16_t)out[1] << 8) | out[0];
+ return (iic2smb_error(error));
}
static int
iicsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
{
- device_t parent = device_get_parent(dev);
- int error, sent;
-
- if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_write(parent, buf, (int)count, &sent, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_stop(parent)))
- goto error;
+ uint8_t bytes[2] = { cmd, count };
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_WR | IIC_M_NOSTOP, nitems(bytes), bytes },
+ { slave, IIC_M_WR | IIC_M_NOSTART, count, buf },
+ };
+ int error;
-error:
- return (error);
+ if (count > 32 || count == 0)
+ return (SMB_EINVAL);
+ error = TRANSFER_MSGS(dev, msgs);
+ return (iic2smb_error(error));
}
static int
iicsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
{
+ struct iic_msg msgs[] = {
+ { slave, IIC_M_WR | IIC_M_NOSTOP, 1, &cmd },
+ { slave, IIC_M_RD | IIC_M_NOSTOP, 1, count },
+ };
+ struct iic_msg block_msg[] = {
+ { slave, IIC_M_RD | IIC_M_NOSTART, 0, buf },
+ };
device_t parent = device_get_parent(dev);
- int error, sent, read;
-
- if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT)))
- return (error);
-
- if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT)))
- goto error;
-
- if ((error = iicbus_read(parent, buf, (int)*count, &read,
- IIC_LAST_READ, IICBUS_TIMEOUT)))
- goto error;
- *count = read;
+ int error;
+ u_char bufsz;
-error:
- iicbus_stop(parent);
- return (error);
+ /* Stash output buffer size before overwriting it. */
+ bufsz = *count;
+ if (bufsz == 0)
+ return (SMB_EINVAL);
+
+ /* Have to do this because the command is split in two transfers. */
+ error = iicbus_request_bus(parent, dev, IIC_WAIT);
+ if (error == 0)
+ error = TRANSFER_MSGS(dev, msgs);
+ if (error == 0) {
+ /*
+ * If the slave offers an empty or a too long reply,
+ * read one byte to generate the stop or abort.
+ * XXX 32 is hardcoded until SMB_MAXBLOCKSIZE is restored
+ * to sanity.
+ */
+ if (*count > 32 || *count == 0)
+ block_msg[0].len = 1;
+ /* If longer than the buffer, then clamp at the buffer size. */
+ if (*count > bufsz)
+ block_msg[0].len = bufsz;
+ else
+ block_msg[0].len = *count;
+ error = TRANSFER_MSGS(dev, block_msg);
+ if (*count > 32 || *count == 0)
+ error = SMB_EINVAL;
+ }
+ (void)iicbus_release_bus(parent, dev);
+ return (iic2smb_error(error));
}
DRIVER_MODULE(iicsmb, iicbus, iicsmb_driver, iicsmb_devclass, 0, 0);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jul 4, 1:11 PM (6 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34671180
Default Alt Text
D8170.id21132.diff (9 KB)
Attached To
Mode
D8170: convert iicsmb to use iicbus_transfer for all operations
Attached
Detach File
Event Timeline
Log In to Comment