Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135576529
D1955.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
19 KB
Referenced Files
None
Subscribers
None
D1955.id.diff
View Options
Index: head/share/man/man4/smb.4
===================================================================
--- head/share/man/man4/smb.4
+++ head/share/man/man4/smb.4
@@ -1,5 +1,6 @@
.\" Copyright (c) 1998, Nicolas Souchu
.\" Copyright (c) 2004, Joerg Wunsch
+.\" Copyright (c) 2015, Michael Gmelin <freebsd@grem.de>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 6, 2009
+.Dd April 25, 2015
.Dt SMB 4
.Os
.Sh NAME
@@ -49,21 +50,24 @@
#include <sys/types.h>
struct smbcmd {
- char cmd;
- int count;
- u_char slave;
+ u_char cmd;
+ u_char reserved;
+ u_short op;
union {
- char byte;
- short word;
-
- char *byte_ptr;
- short *word_ptr;
-
- struct {
- short sdata;
- short *rdata;
- } process;
- } data;
+ char byte;
+ char buf[2];
+ short word;
+ } wdata;
+ union {
+ char byte;
+ char buf[2];
+ short word;
+ } rdata;
+ int slave;
+ char *wbuf; /* use wdata if NULL */
+ int wcount;
+ char *rbuf; /* use rdata if NULL */
+ int rcount;
};
.Ed
.Pp
@@ -107,14 +111,14 @@
command first sends the byte from the
.Fa cmd
field to the device, followed by the byte given in
-.Fa data.byte .
+.Fa wdata.byte .
.It Dv SMB_WRITEW Ta
The
.Em WriteWord
command first sends the byte from the
.Fa cmd
field to the device, followed by the word given in
-.Fa data.word .
+.Fa wdata.word .
Note that the SMBus byte-order is little-endian by definition.
.It Dv SMB_READB Ta
The
@@ -123,8 +127,8 @@
.Fa cmd
field to the device, and then reads one byte of data from
the device.
-The returned data will be stored in the location pointed to by
-.Fa data.byte_ptr .
+The returned data will be stored in
+.Fa rdata.byte .
.It Dv SMB_READW Ta
The
.Em ReadWord
@@ -132,29 +136,33 @@
.Fa cmd
field to the device, and then reads one word of data from
the device.
-The returned data will be stored in the location pointed to by
-.Fa data.word_ptr .
+The returned data will be stored in
+.Fa rdata.word .
.It Dv SMB_PCALL Ta
The
.Em ProcedureCall
command first sends the byte from the
.Fa cmd
field to the device, followed by the word provided in
-.Fa data.process.sdata .
+.Fa wdata.word .
It then reads one word of data from the device, and returns it
-in the location pointed to by
-.Fa data.process.rdata .
+in
+.Fa rdata.word .
.It Dv SMB_BWRITE Ta
The
.Em BlockWrite
command first sends the byte from the
.Fa cmd
field to the device, followed by
-.Fa count
+.Fa wcount
bytes of data that are taken from the buffer pointed to by
-.Fa data.byte_ptr .
+.Fa wbuf .
The SMBus specification mandates that no more than 32 bytes of
-data can be transferred in a single block read or write command.
+data can be transferred in a single block read or write command,
+but since
+.Xr smbus 4
+is also used to access I2C devices, the limit has been increased
+to 1024.
This value is available in the constant
.Dv SMB_MAXBLOCKSIZE .
.It Dv SMB_BREAD Ta
@@ -163,10 +171,38 @@
command first sends the byte from the
.Fa cmd
field to the device, and then reads
-.Fa count
+.Fa rcount
bytes of data that from the device.
These data will be returned in the buffer pointed to by
-.Fa data.byte_ptr .
+.Fa rbuf .
+.It Dv SMB_TRANS Ta
+The
+.Em Trans
+command sends an SMB roll-up transaction with flags that also allow it to
+be used for (mostly) I2C pass-through and with with 10-bit addresses.
+This function can be used to roll up all of the above functions.
+It first sends the byte from the
+.Fa cmd
+field to the device, followed by
+.Fa wcount
+bytes of data that are taken from the buffer pointed to by
+.Fa wbuf ,
+then reads
+.Fa rcount
+bytes of data that from the device.
+These data will be returned in the buffer pointed to by
+.Fa rbuf .
+.Pp
+The following flags are allowed in
+.Fa op :
+.Pp
+.Bd -literal -compact
+SMB_TRANS_NOSTOP Do not send STOP at end
+SMB_TRANS_NOCMD Ignore cmd field (do not tx)
+SMB_TRANS_NOCNT Do not tx or rx count field
+SMB_TRANS_7BIT Change address mode to 7-bit
+SMB_TRANS_10BIT Change address mode to 10-bit
+.Ed
.El
.Pp
The
@@ -201,4 +237,7 @@
.Sh AUTHORS
This
manual page was written by
-.An Nicolas Souchu .
+.An Nicolas Souchu
+and extended by
+.An Michael Gmelin Aq freebsd@grem.de
+.
Index: head/sys/dev/smbus/smb.h
===================================================================
--- head/sys/dev/smbus/smb.h
+++ head/sys/dev/smbus/smb.h
@@ -32,27 +32,33 @@
#include <sys/ioccom.h>
struct smbcmd {
- char cmd;
- int count;
- u_char slave;
+ u_char cmd;
+ u_char reserved;
+ u_short op;
union {
- char byte;
- short word;
-
- char *byte_ptr;
- short *word_ptr;
-
- struct {
- short sdata;
- short *rdata;
- } process;
- } data;
+ char byte;
+ char buf[2];
+ short word;
+ } wdata;
+ union {
+ char byte;
+ char buf[2];
+ short word;
+ } rdata;
+ int slave;
+ char *wbuf; /* use wdata if NULL */
+ int wcount;
+ char *rbuf; /* use rdata if NULL */
+ int rcount;
};
/*
* SMBus spec 2.0 says block transfers may be at most 32 bytes.
+ * We use SMBus for i2c as well, make the size limit something more
+ * reasonable. Keep in mind that a char buf array is declared on the
+ * kernel stack.
*/
-#define SMB_MAXBLOCKSIZE 32
+#define SMB_MAXBLOCKSIZE 1024
#define SMB_QUICK_WRITE _IOW('i', 1, struct smbcmd)
#define SMB_QUICK_READ _IOW('i', 2, struct smbcmd)
@@ -66,5 +72,6 @@
#define SMB_BWRITE _IOW('i', 10, struct smbcmd)
#define SMB_OLD_BREAD _IOW('i', 11, struct smbcmd)
#define SMB_BREAD _IOWR('i', 11, struct smbcmd)
+#define SMB_TRANS _IOWR('i', 12, struct smbcmd)
#endif
Index: head/sys/dev/smbus/smb.c
===================================================================
--- head/sys/dev/smbus/smb.c
+++ head/sys/dev/smbus/smb.c
@@ -26,10 +26,6 @@
* $FreeBSD$
*/
-#ifdef HAVE_KERNEL_OPTION_HEADERS
-#include "opt_compat.h"
-#endif
-
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -104,19 +100,24 @@
static int
smb_probe(device_t dev)
{
- device_set_desc(dev, "SMBus generic I/O");
+ if (smbus_get_addr(dev) != -1)
+ return (ENXIO);
- return (0);
+ device_set_desc(dev, "SMBus generic I/O");
+ return (BUS_PROBE_NOWILDCARD);
}
static int
smb_attach(device_t dev)
{
struct smb_softc *sc = device_get_softc(dev);
-
+ int unit;
+
+ unit = device_get_unit(dev);
sc->sc_dev = dev;
- sc->sc_devnode = make_dev(&smb_cdevsw, device_get_unit(dev),
- UID_ROOT, GID_WHEEL, 0600, "smb%d", device_get_unit(dev));
+
+ sc->sc_devnode = make_dev(&smb_cdevsw, unit, UID_ROOT, GID_WHEEL,
+ 0600, "smb%d", unit);
sc->sc_devnode->si_drv1 = sc;
mtx_init(&sc->sc_lock, device_get_nameunit(dev), NULL, MTX_DEF);
@@ -174,9 +175,16 @@
struct smb_softc *sc = dev->si_drv1;
device_t smbdev = sc->sc_dev;
int error;
- short w;
- u_char count;
- char c;
+ int unit;
+ u_char bcount;
+
+ /*
+ * If a specific slave device is being used, override any passed-in
+ * slave.
+ */
+ unit = dev2unit(dev);
+ if (unit & 0x0400)
+ s->slave = unit & 0x03ff;
parent = device_get_parent(smbdev);
@@ -208,77 +216,101 @@
case SMB_WRITEB:
error = smbus_error(smbus_writeb(parent, s->slave, s->cmd,
- s->data.byte));
+ s->wdata.byte));
break;
case SMB_WRITEW:
error = smbus_error(smbus_writew(parent, s->slave,
- s->cmd, s->data.word));
+ s->cmd, s->wdata.word));
break;
case SMB_READB:
- if (s->data.byte_ptr) {
- error = smbus_error(smbus_readb(parent, s->slave,
- s->cmd, &c));
- if (error)
- break;
- error = copyout(&c, s->data.byte_ptr,
- sizeof(*(s->data.byte_ptr)));
+ error = smbus_error(smbus_readb(parent, s->slave, s->cmd,
+ &s->rdata.byte));
+ if (error)
+ break;
+ if (s->rbuf && s->rcount >= 1) {
+ error = copyout(&s->rdata.byte, s->rbuf, 1);
+ s->rcount = 1;
}
break;
case SMB_READW:
- if (s->data.word_ptr) {
- error = smbus_error(smbus_readw(parent, s->slave,
- s->cmd, &w));
- if (error == 0) {
- error = copyout(&w, s->data.word_ptr,
- sizeof(*(s->data.word_ptr)));
- }
+ error = smbus_error(smbus_readw(parent, s->slave, s->cmd,
+ &s->rdata.word));
+ if (error)
+ break;
+ if (s->rbuf && s->rcount >= 2) {
+ buf[0] = (u_char)s->rdata.word;
+ buf[1] = (u_char)(s->rdata.word >> 8);
+ error = copyout(buf, s->rbuf, 2);
+ s->rcount = 2;
}
break;
case SMB_PCALL:
- if (s->data.process.rdata) {
-
- error = smbus_error(smbus_pcall(parent, s->slave, s->cmd,
- s->data.process.sdata, &w));
- if (error)
- break;
- error = copyout(&w, s->data.process.rdata,
- sizeof(*(s->data.process.rdata)));
+ error = smbus_error(smbus_pcall(parent, s->slave, s->cmd,
+ s->wdata.word, &s->rdata.word));
+ if (error)
+ break;
+ if (s->rbuf && s->rcount >= 2) {
+ buf[0] = (u_char)s->rdata.word;
+ buf[1] = (u_char)(s->rdata.word >> 8);
+ error = copyout(buf, s->rbuf, 2);
+ s->rcount = 2;
}
-
+
break;
case SMB_BWRITE:
- if (s->count && s->data.byte_ptr) {
- if (s->count > SMB_MAXBLOCKSIZE)
- s->count = SMB_MAXBLOCKSIZE;
- error = copyin(s->data.byte_ptr, buf, s->count);
- if (error)
- break;
- error = smbus_error(smbus_bwrite(parent, s->slave,
- s->cmd, s->count, buf));
+ if (s->wcount < 0) {
+ error = EINVAL;
+ break;
}
+ if (s->wcount > SMB_MAXBLOCKSIZE)
+ s->wcount = SMB_MAXBLOCKSIZE;
+ if (s->wcount)
+ error = copyin(s->wbuf, buf, s->wcount);
+ if (error)
+ break;
+ error = smbus_error(smbus_bwrite(parent, s->slave, s->cmd,
+ s->wcount, buf));
break;
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD6)
- case SMB_OLD_BREAD:
-#endif
case SMB_BREAD:
- if (s->count && s->data.byte_ptr) {
- count = min(s->count, SMB_MAXBLOCKSIZE);
- error = smbus_error(smbus_bread(parent, s->slave,
- s->cmd, &count, buf));
- if (error)
- break;
- error = copyout(buf, s->data.byte_ptr,
- min(count, s->count));
- s->count = count;
+ if (s->rcount < 0) {
+ error = EINVAL;
+ break;
+ }
+ if (s->rcount > SMB_MAXBLOCKSIZE)
+ s->rcount = SMB_MAXBLOCKSIZE;
+ error = smbus_error(smbus_bread(parent, s->slave, s->cmd,
+ &bcount, buf));
+ if (error)
+ break;
+ if (s->rcount > bcount)
+ s->rcount = bcount;
+ error = copyout(buf, s->rbuf, s->rcount);
+ break;
+
+ case SMB_TRANS:
+ if (s->rcount < 0 || s->wcount < 0) {
+ error = EINVAL;
+ break;
}
+ if (s->rcount > SMB_MAXBLOCKSIZE)
+ s->rcount = SMB_MAXBLOCKSIZE;
+ if (s->wcount > SMB_MAXBLOCKSIZE)
+ s->wcount = SMB_MAXBLOCKSIZE;
+ if (s->wcount)
+ error = copyin(s->wbuf, buf, s->wcount);
+ if (error)
+ break;
+ error = smbus_error(smbus_trans(parent, s->slave, s->cmd,
+ s->op, buf, s->wcount, buf, s->rcount, &s->rcount));
+ if (error == 0)
+ error = copyout(buf, s->rbuf, s->rcount);
break;
-
default:
error = ENOTTY;
}
Index: head/sys/dev/smbus/smbconf.h
===================================================================
--- head/sys/dev/smbus/smbconf.h
+++ head/sys/dev/smbus/smbconf.h
@@ -68,9 +68,30 @@
#define SMB_QREAD 0x1
/*
+ * smbus transction op with pass-thru capabilities
+ *
+ * This smbus function is capable of doing a smbus command transaction
+ * (read or write), and can be flagged to not issue the 'cmd' and/or
+ * issue or expect a count field as well as flagged for chaining (no STOP),
+ * which gives it an i2c pass-through capability.
+ *
+ * NOSTOP- Caller chaining transactions, do not issue STOP
+ * NOCMD- Do not transmit the command field
+ * NOCNT- Do not transmit (wr) or expect (rd) the count field
+ */
+#define SMB_TRANS_NOSTOP 0x0001 /* do not send STOP at end */
+#define SMB_TRANS_NOCMD 0x0002 /* ignore cmd field (do not tx) */
+#define SMB_TRANS_NOCNT 0x0004 /* do not tx or rx count field */
+#define SMB_TRANS_7BIT 0x0008 /* change address mode to 7-bit */
+#define SMB_TRANS_10BIT 0x0010 /* change address mode to 10-bit */
+#define SMB_TRANS_NOREPORT 0x0020 /* do not report errors */
+
+/*
* ivars codes
*/
-#define SMBUS_IVAR_ADDR 0x1 /* slave address of the device */
+enum smbus_ivars {
+ SMBUS_IVAR_ADDR, /* slave address of the device */
+};
int smbus_request_bus(device_t, device_t, int);
int smbus_release_bus(device_t, device_t);
@@ -79,7 +100,12 @@
void smbus_intr(device_t, u_char, char low, char high, int error);
-u_char smbus_get_addr(device_t);
+#define SMBUS_ACCESSOR(var, ivar, type) \
+ __BUS_ACCESSOR(smbus, var, SMBUS, ivar, type)
+
+SMBUS_ACCESSOR(addr, ADDR, int)
+
+#undef SMBUS_ACCESSOR
extern driver_t smbus_driver;
extern devclass_t smbus_devclass;
@@ -104,6 +130,9 @@
(SMBUS_BWRITE(device_get_parent(bus), slave, cmd, count, buf))
#define smbus_bread(bus,slave,cmd,count,buf) \
(SMBUS_BREAD(device_get_parent(bus), slave, cmd, count, buf))
+#define smbus_trans(bus,slave,cmd,op,wbuf,wcount,rbuf,rcount,actualp) \
+ (SMBUS_TRANS(device_get_parent(bus), slave, cmd, op, \
+ wbuf, wcount, rbuf, rcount, actualp))
#define SMBUS_MODVER 1
#define SMBUS_MINVER 1
Index: head/sys/dev/smbus/smbus.h
===================================================================
--- head/sys/dev/smbus/smbus.h
+++ head/sys/dev/smbus/smbus.h
@@ -29,9 +29,13 @@
#ifndef __SMBUS_H
#define __SMBUS_H
+#define SMBUS_ADDR_MIN 0x10
+#define SMBUS_ADDR_MAX 0x70
+
struct smbus_softc {
device_t owner; /* smbus owner device structure */
struct mtx lock;
+ unsigned char addrs[SMBUS_ADDR_MAX];
};
void smbus_generic_intr(device_t dev, u_char devaddr, char low, char high, int err);
Index: head/sys/dev/smbus/smbus.c
===================================================================
--- head/sys/dev/smbus/smbus.c
+++ head/sys/dev/smbus/smbus.c
@@ -33,11 +33,15 @@
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
-#include <sys/bus.h>
+#include <sys/bus.h>
#include <dev/smbus/smbconf.h>
#include <dev/smbus/smbus.h>
+#include "smbus_if.h"
+#include "bus_if.h"
+
+
/*
* Autoconfiguration and support routines for System Management bus
*/
@@ -49,6 +53,13 @@
static int smbus_attach(device_t);
static int smbus_detach(device_t);
+static int smbus_child_location_str(device_t parent, device_t child,
+ char *buf, size_t buflen);
+static int smbus_print_child(device_t parent, device_t child);
+static void smbus_probe_device(device_t dev, u_char* addr);
+static int smbus_read_ivar(device_t parent, device_t child, int which,
+ uintptr_t *result);
+
static device_method_t smbus_methods[] = {
/* device interface */
DEVMETHOD(device_probe, smbus_probe),
@@ -57,6 +68,10 @@
/* bus interface */
DEVMETHOD(bus_add_child, bus_generic_add_child),
+ DEVMETHOD(bus_child_location_str, smbus_child_location_str),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ DEVMETHOD(bus_print_child, smbus_print_child),
+ DEVMETHOD(bus_read_ivar, smbus_read_ivar),
DEVMETHOD_END
};
@@ -87,9 +102,14 @@
smbus_attach(device_t dev)
{
struct smbus_softc *sc = device_get_softc(dev);
+ unsigned char addr;
mtx_init(&sc->lock, device_get_nameunit(dev), "smbus", MTX_DEF);
bus_generic_probe(dev);
+ for (addr = SMBUS_ADDR_MIN; addr < SMBUS_ADDR_MAX; ++addr) {
+ sc->addrs[addr] = addr;
+ smbus_probe_device(dev, &sc->addrs[addr]);
+ }
bus_generic_attach(dev);
return (0);
@@ -114,4 +134,70 @@
{
}
+static void
+smbus_probe_device(device_t dev, u_char* addr)
+{
+ device_t child;
+ int error;
+ u_char cmd;
+ u_char buf[2];
+
+ cmd = 0x01;
+ error = smbus_trans(dev, *addr, cmd,
+ SMB_TRANS_NOCNT | SMB_TRANS_NOREPORT,
+ NULL, 0, buf, 1, NULL);
+ if (error == 0) {
+ if (bootverbose)
+ device_printf(dev, "Probed address 0x%02x\n", *addr);
+ child = device_add_child(dev, NULL, -1);
+ device_set_ivars(child, addr);
+ }
+}
+
+static int
+smbus_child_location_str(device_t parent, device_t child, char *buf,
+ size_t buflen)
+{
+ unsigned char *addr;
+
+ addr = device_get_ivars(child);
+ if (addr)
+ snprintf(buf, buflen, "addr=0x%x", *addr);
+ else if (buflen)
+ buf[0] = 0;
+ return (0);
+}
+
+static int
+smbus_print_child(device_t parent, device_t child)
+{
+ unsigned char *addr;
+ int retval;
+
+ addr = device_get_ivars(child);
+ retval = bus_print_child_header(parent, child);
+ if (addr)
+ retval += printf(" at addr 0x%x", *addr);
+ retval += bus_print_child_footer(parent, child);
+
+ return (retval);
+}
+
+static int
+smbus_read_ivar(device_t parent, device_t child, int which,
+ uintptr_t *result)
+{
+ unsigned char *addr;
+
+ addr = device_get_ivars(child);
+ switch (which) {
+ case SMBUS_IVAR_ADDR:
+ *result = (addr == NULL) ? -1 : *addr;
+ break;
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
MODULE_VERSION(smbus, SMBUS_MODVER);
Index: head/sys/dev/smbus/smbus_if.m
===================================================================
--- head/sys/dev/smbus/smbus_if.m
+++ head/sys/dev/smbus/smbus_if.m
@@ -149,3 +149,20 @@
u_char *count;
char *buf;
};
+
+#
+# SMB roll-up transaction with flags that also allow it to be
+# used for (mostly) i2c pass-through and with 10-bit addresses.
+# This function can be used to roll-up all of the above functions.
+#
+METHOD int trans {
+ device_t dev;
+ int slave;
+ char cmd;
+ int op;
+ char *wbuf;
+ int wcount;
+ char *rbuf;
+ int rcount;
+ int *actualp;
+};
Index: head/usr.sbin/smbmsg/smbmsg.c
===================================================================
--- head/usr.sbin/smbmsg/smbmsg.c
+++ head/usr.sbin/smbmsg/smbmsg.c
@@ -163,7 +163,8 @@
}
if (iflag == 1 && oflag == -1) {
/* command + 1 byte input: read byte op. */
- c.data.byte_ptr = ibuf;
+ c.rbuf = ibuf;
+ c.rcount = iflag;
if (ioctl(fd, SMB_READB, &c) == -1)
return (-1);
printf(fmt, (int)(unsigned char)ibuf[0]);
@@ -171,11 +172,12 @@
return (0);
} else if (iflag == -1 && oflag == 1) {
/* command + 1 byte output: write byte op. */
- c.data.byte = obuf[0];
+ c.wdata.byte = obuf[0];
return (ioctl(fd, SMB_WRITEB, &c));
} else if (wflag && iflag == 2 && oflag == -1) {
/* command + 2 bytes input: read word op. */
- c.data.word_ptr = &iword;
+ c.rbuf = (char*) &iword;
+ c.rcount = iflag;
if (ioctl(fd, SMB_READW, &c) == -1)
return (-1);
printf(fmt, (int)(unsigned short)iword);
@@ -183,15 +185,16 @@
return (0);
} else if (wflag && iflag == -1 && oflag == 2) {
/* command + 2 bytes output: write word op. */
- c.data.word = oword;
+ c.wdata.word = oword;
return (ioctl(fd, SMB_WRITEW, &c));
} else if (wflag && iflag == 2 && oflag == 2) {
/*
* command + 2 bytes output + 2 bytes input:
* "process call" op.
*/
- c.data.process.sdata = oword;
- c.data.process.rdata = &iword;
+ c.wdata.word = oword;
+ c.rbuf = (char*) &iword;
+ c.rcount = iflag;
if (ioctl(fd, SMB_PCALL, &c) == -1)
return (-1);
printf(fmt, (int)(unsigned short)iword);
@@ -199,8 +202,8 @@
return (0);
} else if (iflag > 1 && oflag == -1) {
/* command + > 1 bytes of input: block read */
- c.data.byte_ptr = ibuf;
- c.count = iflag;
+ c.rbuf = ibuf;
+ c.rcount = iflag;
if (ioctl(fd, SMB_BREAD, &c) == -1)
return (-1);
for (i = 0; i < iflag; i++) {
@@ -212,8 +215,8 @@
return (0);
} else if (iflag == -1 && oflag > 1) {
/* command + > 1 bytes of output: block write */
- c.data.byte_ptr = obuf;
- c.count = oflag;
+ c.wbuf = obuf;
+ c.wcount = oflag;
return (ioctl(fd, SMB_BWRITE, &c));
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 11, 11:45 PM (3 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25184817
Default Alt Text
D1955.id.diff (19 KB)
Attached To
Mode
D1955: Expand the SMBUS API to add a smbus_trans() function.
Attached
Detach File
Event Timeline
Log In to Comment