Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Apr 2015 16:15:02 +0000 (UTC)
From:      Michael Gmelin <grembo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r281985 - in head: share/man/man4 sys/dev/smbus usr.sbin/smbmsg
Message-ID:  <201504251615.t3PGF2Z1096937@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: grembo (ports committer)
Date: Sat Apr 25 16:15:01 2015
New Revision: 281985
URL: https://svnweb.freebsd.org/changeset/base/281985

Log:
  Expand SMBUS API to add smbus_trans() function.
  
  Differential Revision:	https://reviews.freebsd.org/D1955
  Reviewed by:	adrian, jhb, wblock
  Approved by:	adrian, jhb

Modified:
  head/share/man/man4/smb.4
  head/sys/dev/smbus/smb.c
  head/sys/dev/smbus/smb.h
  head/sys/dev/smbus/smbconf.h
  head/sys/dev/smbus/smbus.c
  head/sys/dev/smbus/smbus.h
  head/sys/dev/smbus/smbus_if.m
  head/usr.sbin/smbmsg/smbmsg.c

Modified: head/share/man/man4/smb.4
==============================================================================
--- head/share/man/man4/smb.4	Sat Apr 25 16:12:06 2015	(r281984)
+++ head/share/man/man4/smb.4	Sat Apr 25 16:15:01 2015	(r281985)
@@ -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 @@ as its argument.
 #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 @@ The
 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 @@ command first sends the byte from the
 .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 @@ command first sends the byte from the
 .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 @@ The
 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 @@ manual page first appeared in
 .Sh AUTHORS
 This
 manual page was written by
-.An Nicolas Souchu .
+.An Nicolas Souchu
+and extended by
+.An Michael Gmelin Aq freebsd@grem.de
+.

Modified: head/sys/dev/smbus/smb.c
==============================================================================
--- head/sys/dev/smbus/smb.c	Sat Apr 25 16:12:06 2015	(r281984)
+++ head/sys/dev/smbus/smb.c	Sat Apr 25 16:15:01 2015	(r281985)
@@ -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 @@ smb_identify(driver_t *driver, device_t 
 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 @@ smbioctl(struct cdev *dev, u_long cmd, c
 	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 @@ smbioctl(struct cdev *dev, u_long cmd, c
 
 	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;
 	}

Modified: head/sys/dev/smbus/smb.h
==============================================================================
--- head/sys/dev/smbus/smb.h	Sat Apr 25 16:12:06 2015	(r281984)
+++ head/sys/dev/smbus/smb.h	Sat Apr 25 16:15:01 2015	(r281985)
@@ -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 @@ struct smbcmd {
 #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

Modified: head/sys/dev/smbus/smbconf.h
==============================================================================
--- head/sys/dev/smbus/smbconf.h	Sat Apr 25 16:12:06 2015	(r281984)
+++ head/sys/dev/smbus/smbconf.h	Sat Apr 25 16:15:01 2015	(r281985)
@@ -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 @@ int	smbus_error(int error);
 
 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 @@ extern devclass_t smbus_devclass;
 	(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

Modified: head/sys/dev/smbus/smbus.c
==============================================================================
--- head/sys/dev/smbus/smbus.c	Sat Apr 25 16:12:06 2015	(r281984)
+++ head/sys/dev/smbus/smbus.c	Sat Apr 25 16:15:01 2015	(r281985)
@@ -33,11 +33,15 @@ __FBSDID("$FreeBSD$");
 #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_probe(device_t);
 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 @@ static device_method_t smbus_methods[] =
 
 	/* 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 @@ static int
 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 @@ smbus_generic_intr(device_t dev, u_char 
 {
 }
 
+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);

Modified: head/sys/dev/smbus/smbus.h
==============================================================================
--- head/sys/dev/smbus/smbus.h	Sat Apr 25 16:12:06 2015	(r281984)
+++ head/sys/dev/smbus/smbus.h	Sat Apr 25 16:15:01 2015	(r281985)
@@ -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);

Modified: head/sys/dev/smbus/smbus_if.m
==============================================================================
--- head/sys/dev/smbus/smbus_if.m	Sat Apr 25 16:12:06 2015	(r281984)
+++ head/sys/dev/smbus/smbus_if.m	Sat Apr 25 16:15:01 2015	(r281985)
@@ -149,3 +149,20 @@ METHOD int bread {
 	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;
+};

Modified: head/usr.sbin/smbmsg/smbmsg.c
==============================================================================
--- head/usr.sbin/smbmsg/smbmsg.c	Sat Apr 25 16:12:06 2015	(r281984)
+++ head/usr.sbin/smbmsg/smbmsg.c	Sat Apr 25 16:15:01 2015	(r281985)
@@ -163,7 +163,8 @@ do_io(void)
 	}
 	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 @@ do_io(void)
 		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 @@ do_io(void)
 		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 @@ do_io(void)
 		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 @@ do_io(void)
 		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));
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504251615.t3PGF2Z1096937>