changeset 89:1a63316a2a5d

8071686: [DIO1.0.1] I2CDevice updates Summary: I2CDevice support Transactional interface optionally. Reviewed-by: jld
author snazarki
date Wed, 28 Jan 2015 13:51:47 +0400
parents 344490bdebb8
children ecdc22ce1f87
files src/share/classes/com/oracle/dio/i2cbus/impl/I2CSlaveImpl.java src/share/classes/jdk/dio/i2cbus/I2CCombinedMessage.java src/share/classes/jdk/dio/i2cbus/I2CDevice.java src/share/classes/jdk/dio/i2cbus/package-info.java
diffstat 4 files changed, 138 insertions(+), 214 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/oracle/dio/i2cbus/impl/I2CSlaveImpl.java	Mon Jan 26 17:34:34 2015 +0300
+++ b/src/share/classes/com/oracle/dio/i2cbus/impl/I2CSlaveImpl.java	Wed Jan 28 13:51:47 2015 +0400
@@ -47,11 +47,6 @@
     static final int I2C_COMBINED_END = 2;
     static final int I2C_COMBINED_BODY = 3;
 
-    /**
-     * Hidden transaction created when I2CDevice.begin is called
-     */
-    private I2CCombinedMessage internalTransaction;
-
     I2CSlaveImpl(DeviceDescriptor<I2CDevice> dscr, int mode) throws
             DeviceNotFoundException, InvalidDeviceConfigException {
         super(dscr, mode);
@@ -134,20 +129,7 @@
 
         doCheck(skip, dst);
 
-        I2CCombinedMessage message = null;
-        int pos = 0;
-        synchronized(this) {
-            message = internalTransaction;
-            if (null != message) {
-                pos  = dst.position();
-                message.appendRead(this, skip, dst);
-            }
-        }
-        if (null != message) {
-            return 0;
-        } else {
-            return transfer(I2C_REGULAR, skip, dst);
-        }
+        return transfer(I2C_REGULAR, skip, dst);
     }
 
     @Override
@@ -179,21 +161,7 @@
     public int write(ByteBuffer src) throws IOException,
             UnavailableDeviceException, ClosedDeviceException {
         doCheck(0, src);
-
-        I2CCombinedMessage message = null;
-        int pos = 0;
-        synchronized(this) {
-            message = internalTransaction;
-            if (null != message) {
-                pos  = src.position();
-                message.appendWrite(this,src);
-            }
-        }
-        if (null != message) {
-            return 0;
-        } else {
-            return transfer(I2C_REGULAR, -1, src);
-        }
+        return transfer(I2C_REGULAR, -1, src);
     }
 
 
@@ -299,46 +267,6 @@
         return ret;
     }
 
-    /*
-     *  It is acceptable to sync on {@code this} object since this
-     *  is short operation
-     */
-    @Override
-    public void begin() throws ClosedDeviceException, IOException {
-        checkPowerState();
-        synchronized(this) {
-            if (null != internalTransaction) {
-                throw new IllegalStateException();
-            }
-            // we do not realy on driver ability to keep bus locked between begin/end.
-            // Instead we buffer all subsequent read/write operations inside
-            // single transaction
-            internalTransaction = new I2CCombinedMessage();
-        }
-    }
-
-    @Override
-    public void end() throws ClosedDeviceException, IOException {
-        I2CCombinedMessage message;
-        checkOpen();
-        synchronized(this) {
-            message = internalTransaction;
-            // cleaning variable gives a chance to prepare next transaction
-            // while current is ongoing
-            internalTransaction = null;
-        }
-        if (null == message) {
-            throw new IllegalStateException("No transaction in progress");
-        }
-
-        try {
-            tryLock(1);
-            message.transfer();
-        } finally {
-            unlock();
-        }
-    }
-
     protected synchronized int getGrpID() {
         return getGrpID0();
     }
--- a/src/share/classes/jdk/dio/i2cbus/I2CCombinedMessage.java	Mon Jan 26 17:34:34 2015 +0300
+++ b/src/share/classes/jdk/dio/i2cbus/I2CCombinedMessage.java	Wed Jan 28 13:51:47 2015 +0400
@@ -33,7 +33,7 @@
 /**
  * The {@code I2CCombinedMessage} interface provides methods for constructing a
  * combined message. A combined message may be constituted of at least two reads
- * and/or writes to one or more I2C slaves. A combined message starts with a
+ * and/or writes to one or more I2C slaves (connected to the same bus). A combined message starts with a
  * START bit and ends with a STOP bit. But each of read and write messages
  * constituting the combined message following the very first of these messages
  * starts with a REPEATED START bit (one that is not preceded by a STOP bit).
@@ -45,7 +45,7 @@
  *         I2CDevice slave2 = DeviceManager.open("EEPROM", I2CDevice.class, null)) {
  *     ByteBuffer temp = ByteBuffer.allocateDirect(4);
  *     byte[] addr = new byte[]{...};
- *     int byteRead = slave1.getBus().createCombinedMessage()
+ *     int bytesRead = slave1.getBus().createCombinedMessage()
  *             .appendRead(slave1, temp) // Reads the temperature from TEMP sensor
  *             .appendWrite(slave2, ByteBuffer.wrap(addr)) // Writes the address to EEPROM to select the location
  *             .appendWrite(slave2, temp) // Writes the temperature at the selected EEPROM address
@@ -55,7 +55,7 @@
  * }
  * </pre>
  * </blockquote> The preceding example is using a
- * <em>try-with-resources</em> statement. The
+ * <em>try-with-resources</em> statement; the
  * {@link I2CDevice#close I2CDevice.close} method is automatically invoked by
  * the platform at the end of the statement.
  * <p />
@@ -73,7 +73,7 @@
 
     /**
      * Appends a read message/operation from the provided I2C slave device.
-     * Reads up to {@code rwBuf.remaining()} bytes of data from this slave
+     * Reads up to {@code rxBuf.remaining()} bytes of data from the provided slave
      * device into the buffer {@code rxBuf}.
      * <p />
      * Buffers are not safe for use by multiple concurrent threads so care should
@@ -86,20 +86,20 @@
      * @param slave the I2C slave device to read from.
      * @param rxBuf the buffer into which the data is read.
      * @return a reference to this {@code I2CCombinedMessage} object.
-     * @throws NullPointerException If {@code rxBuf} is {@code null}.
+     * @throws NullPointerException if {@code rxBuf} is {@code null}.
      * @throws IllegalStateException if this message has already been
-     * transferred once.
+     * transferred once and therefore the message assembling is over.
      * @throws ClosedDeviceException if the device has been closed.
      * @throws IllegalArgumentException if appending the read operation to a
-     * slave on a different bus.
+     * slave on a different bus than the one this {@code I2CCombinedMessage} object was created for.
      * @throws IOException if some other I/O error occurs.
      */
     I2CCombinedMessage appendRead(I2CDevice slave, ByteBuffer rxBuf) throws IOException, ClosedDeviceException;
 
     /**
      * Appends a read message/operation from the provided I2C slave device.
-     * Reads up to {@code rwBuf.remaining()} bytes of data from this slave
-     * device into the buffer skipping {@code rxBuf} the first {@code rxSkip}
+     * Reads up to {@code rxBuf.remaining()} bytes of data from the provided slave
+     * device into the buffer {@code rxBuf} skipping the first {@code rxSkip}
      * bytes read.
      * <p />
      * Buffers are not safe for use by multiple concurrent threads so care should
@@ -114,12 +114,12 @@
      * before filling in the {@code rxBuf} buffer.
      * @param rxBuf the buffer into which the data is read.
      * @return a reference to this {@code I2CCombinedMessage} object.
-     * @throws NullPointerException If {@code rxBuf} is {@code null}.
+     * @throws NullPointerException if {@code rxBuf} is {@code null}.
      * @throws IllegalStateException if this message has already been
-     * transferred once.
+     * transferred once and therefore the message assembling is over.
      * @throws ClosedDeviceException if the device has been closed.
      * @throws IllegalArgumentException if {@code rxSkip} is negative or if
-     * appending the read operation to a slave on a different bus.
+     * appending the read operation to a slave on a different bus than the one this {@code I2CCombinedMessage} object was created for.
      * @throws IOException if some other I/O error occurs.
      */
     I2CCombinedMessage appendRead(I2CDevice slave, int rxSkip, ByteBuffer rxBuf) throws IOException,
@@ -127,7 +127,7 @@
 
     /**
      * Appends a write message/operation from the provided I2C slave device.
-     * Writes to this slave device {@code txBuff.remaining()} bytes from the
+     * Writes to the provided slave device {@code txBuf.remaining()} bytes from the
      * buffer {@code txBuf}.
      * <p />
      * Buffers are not safe for use by multiple concurrent threads so care should
@@ -140,12 +140,12 @@
      * @param slave the I2C slave device to write to.
      * @param txBuf the buffer containing the bytes to write.
      * @return a reference to this {@code I2CCombinedMessage} object.
-     * @throws NullPointerException If {@code txBuf} is {@code null}.
+     * @throws NullPointerException if {@code txBuf} is {@code null}.
      * @throws IllegalStateException if this message has already been
-     * transferred once.
+     * transferred once and therefore the message assembling is over.
      * @throws ClosedDeviceException if the device has been closed.
      * @throws IllegalArgumentException if appending the write operation to a
-     * slave on a different bus.
+     * slave on a different bus than the one this {@code I2CCombinedMessage} object was created for.
      * @throws IOException if some other I/O error occurs.
      */
     I2CCombinedMessage appendWrite(I2CDevice slave, ByteBuffer txBuf) throws IOException,
@@ -156,14 +156,17 @@
      * contained messages/operations to be sent/executed in the same order they
      * have been appended to this combined message.
      * <p />
+     * This method may be invoked at any time. If another thread has already initiated a read or write
+     * operation upon this slave device, however, then an invocation of this method will block until
+     * the first operation is complete.
+     * <p />
      * Once transferred no additional operation can be appended anymore to this
      * combined message. Any such attempt will result in a
      * {@link IllegalStateException} to be thrown.
-     * <p />
-     * This combined message can be transferred several times. The data transferred
+     * Nevertheless, this {@code I2CCombinedMessage} object can be reused several times to perform
+     * the same sequence of operations. The data transferred
      * to or from each of the provided {@code ByteBuffer}s is determined by its current {@code position}
      * and {@code remaining} attributes at the time this method is call.
-     * The caller is responsible for preparing the buffers between each transfer.
      * <br />
      * Buffers are not safe for use by multiple concurrent threads so care should
      * be taken to not access the provided buffers until the transfer has completed.
--- a/src/share/classes/jdk/dio/i2cbus/I2CDevice.java	Mon Jan 26 17:34:34 2015 +0300
+++ b/src/share/classes/jdk/dio/i2cbus/I2CDevice.java	Wed Jan 28 13:51:47 2015 +0400
@@ -63,34 +63,10 @@
  * <dd>The I2C master issues at least two reads and/or writes to one or more slaves.
  * <dl>
  * <dt><b>To a single slave</b></dt>
- * <dd>An application can explicitly start a combined message using {@link #begin begin}, issues
- * several read or write operations using the {@link #read read} and {@link #write write} methods
- * then end the combined message using {@link #end end}. An application can also use the convenience
- * methods {@link #read(int, int, ByteBuffer) read(subaddress, subaddressSize,...)} and
- * {@link #write(int, int, ByteBuffer) write(subaddress, subaddressSize,...)} that respectively read
- * and write from slave device subaddresses or register addresses. The following example illustrates
- * the use of {@link #begin begin} and {@link #end end} to implement the
- * {@link #read(int, int, ByteBuffer) read(subaddress, subaddressSize,...)} method:
- * <p />
- * <blockquote>
- *
- * <pre>
- * public int read(int subaddress, int subaddressSize, ByteBuffer dstBuf) throws IOException,
- *         UnavailableDeviceException {
- *     if (subaddress &lt; 0 || subaddressSize &lt; 1 || subaddressSize &gt; 4)
- *         throw IllegalArgumentException();
- *     byte[] subaddr = new byte[] { (byte) ((subaddress &gt;&gt; 24) &amp; 0xFF), (byte) ((subaddress &gt;&gt; 16) &amp; 0xFF),
- *             (byte) ((subaddress &gt;&gt; 8) &amp; 0xFF), (byte) ((subaddress &gt;&gt; 0) &amp; 0xFF), };
- *     try {
- *         begin();
- *         write(ByteBuffer.wrap(subaddr, subaddr.length - subaddressSize, subaddressSize)); // Writes the subaddress
- *         return read(dstBuf); // Read the data at that subaddress
- *     } finally {
- *         end();
- *     }
- * }
- * </pre>
- * </blockquote></dd>
+ * <dd> An application can use the methods {@link #read(int, int, ByteBuffer) read(subaddress, subaddressSize,...)} and
+ * {@link #write(int, int, ByteBuffer) write(subaddress, subaddressSize,...)} that rely on combined messages to respectively read
+ * and write from slave device subaddresses or register addresses. Transferring more complex combined messages may be performed
+ * if the {@code I2CDevice} instance implements the {@link jdk.dio.Transactional Transactional} interface (see <a href="#tx">I2C Transactions</a>)  </dd>
  * <dt><b>To several slaves</b></dt>
  * <dd>An application can issue several reads and/or writes to several slaves using a
  * {@link I2CCombinedMessage} object.</dd>
@@ -104,14 +80,43 @@
  * <p/>
  * Opening an {@link I2CDevice} instance is subject to permission checks (see {@link I2CPermission}
  * ).
+ * <h3><a name="tx">I2C Transactions</a></h3>
+ * Depending on the underlying platform and driver capabilities an {@code I2CDevice} instance may additionally implement
+ * the {@link jdk.dio.Transactional Transactional} interface to indicate that it supports I2C transactions. In such a case the {@link jdk.dio.Transactional#begin Transactional.begin}
+ * and {@link jdk.dio.Transactional#end Transactional.end} methods may be used to demarcate the beginning and the end of an I2C transaction.
+ * This typically results in the whole sequence of read and write operations to be part of the same I2C combined message.
+ * The following example illustrates the use of {@link Transactional#begin begin} and {@link Transactional#end end} to implement the
+ * same behavior as that of the {@link #read(int, int, ByteBuffer) read(subaddress, subaddressSize,...)} method:
+ * <blockquote>
  *
+ * <pre>
+ * I2CDevice device = ...;
+ * if (device instanceof Transactional) {
+ *     byte[] subaddr = new byte[] { (byte) ((subaddress &gt;&gt; 24) &amp; 0xFF), (byte) ((subaddress &gt;&gt; 16) &amp; 0xFF),
+ *             (byte) ((subaddress &gt;&gt; 8) &amp; 0xFF), (byte) ((subaddress &gt;&gt; 0) &amp; 0xFF), };
+ *     try {
+ *         ((Transactional) device).begin();
+ *         device.write(ByteBuffer.wrap(subaddr, subaddr.length - subaddressSize, subaddressSize)); // Writes the subaddress
+ *         device.read(dstBuf); // Read the data at that subaddress
+ *     } finally {
+ *         ((Transactional) device).end();
+ *     }
+ * }
+ * </pre>
+ * </blockquote>
+ * <h3>Device Probing Limitations</h3>
+ * Opening an {@code I2CDevice} instance with hardware addressing information and configuration
+ * may be subject to <a href="{@docRoot}/jdk/dio/DeviceManager.html#probing">device probing limitations </a>.
+ *
+ * @see jdk.dio.Transactional
+ * @see I2CCombinedMessage
  * @see I2CPermission
  * @see ClosedDeviceException
  * @since 1.0
  */
 @apimarker.API("device-io_1.0")
 @WeakDontRenameClass
-public interface I2CDevice extends Device<I2CDevice>, ByteChannel, Transactional, BufferAccess<ByteBuffer> {
+public interface I2CDevice extends Device<I2CDevice>, ByteChannel, BufferAccess<ByteBuffer> {
 
     /**
      * The {@code Bus} interface is a simplified abstraction of an I2C bus
@@ -143,45 +148,16 @@
     Bus getBus() throws IOException;
 
     /**
-     * Demarcates the beginning of an I2C transaction so that the subsequent read and write
-     * operations will be part of the same I2C combined message.
-     *
-     * @throws UnavailableDeviceException
-     *             if this device is not currently available - such as it is locked by another
-     *             application.
-     * @throws ClosedDeviceException
-     *             if the device has been closed.
-     * @throws IOException
-     *             if some other I/O error occurs.
-     * @throws IllegalStateException
-     *             if a transaction is already in progress.
-     */
-    @Override
-    void begin() throws IOException, UnavailableDeviceException, ClosedDeviceException;
-
-    /**
-     * Demarcates the end of a transaction hence ending the I2C combined message.
-     *
-     * @throws UnavailableDeviceException
-     *             if this device is not currently available - such as it is locked by another
-     *             application.
-     * @throws ClosedDeviceException
-     *             if the device has been closed.
-     * @throws IOException
-     *             if some other I/O error occurs.
-     * @throws IllegalStateException
-     *             if a transaction is not currently in progress.
-     */
-    @Override
-    void end() throws IOException, UnavailableDeviceException, ClosedDeviceException;
-
-    /**
      * Reads one byte of data from this slave device. The byte is returned as an {@code int} in the
      * range {@code 0} to {@code 255}.
+     * <p />
+     * This method may be invoked at any time. If another thread has already initiated a read or write
+     * operation upon this slave device, however, then an invocation of this method will block until
+     * the first operation is complete.
      *
      * @return the unsigned 8-bit value read.
      * @throws IOException
-     *             if some other I/O error occurs.
+     *             if some other I/O error occurs (e.g. a <em>NACK</em> from the slave device was received).
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
@@ -193,21 +169,38 @@
     /**
      * Reads a sequence of bytes from this slave device into the given buffer.
      * <p />
-     * {@inheritDoc}
+     * An attempt is made to read up to <i>r</i> bytes from the device, where <i>r</i> is the number
+     * of bytes remaining in the buffer, that is, {@code dst.remaining()}, at the moment this method
+     * is invoked.
+     * <p />
+     * Suppose that a byte sequence of length <i>n</i> is read, where <i>{@code 0 <= n <= r}</i>.
+     * This byte sequence will be transferred into the buffer so that the first byte in the sequence
+     * is at index <i>p</i> and the last byte is at index <i>{@code p + n - 1}</i>, where <i>p</i>
+     * is the buffer's position at the moment this method is invoked. Upon return the buffer's
+     * position will be equal to <i>{@code p + n}</i>; its limit will not have changed.
+     * <p />
+     * A read operation will block until the requested <i>r</i> bytes are read.
+     * <p />
+     * This method may be invoked at any time. If another thread has already initiated a read or write
+     * operation upon this slave device, however, then an invocation of this method will block until
+     * the first operation is complete.
+     * <p />
+     * This method may be invoked at any time. If another thread has already
+     * initiated a read upon this device, however, then an invocation
+     * of this method will block until the first operation is complete.
      *
      * @param dst
-     *            The buffer into which bytes are to be transferred
-     * @return The number of bytes read into {@code dst}, possibly zero, or {@code -1} if the device has reached
-     *         end-of-stream
+     *            the buffer into which bytes are to be transferred.
+     * @return the number of bytes read into {@code dst}, possibly zero.
      * @throws NullPointerException
-     *             If {@code dst} is {@code null}.
+     *             if {@code dst} is {@code null}.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
      * @throws ClosedDeviceException
      *             if the device has been closed.
      * @throws IOException
-     *             If some other I/O error occurs
+     *             if some other I/O error occurs (e.g. a <em>NACK</em> from the slave device was received).
      */
     @Override
     int read(ByteBuffer dst) throws IOException, UnavailableDeviceException, ClosedDeviceException;
@@ -223,20 +216,19 @@
      *            the number of read bytes that must be ignored/skipped before filling in the
      *            {@code dst} buffer.
      * @param dst
-     *            The buffer into which bytes are to be transferred
-     * @return The number of bytes read into {@code dst}, possibly zero, or {@code -1} if the device has reached
-     *         end-of-stream
+     *            the buffer into which bytes are to be transferred.
+     * @return the number of bytes read into {@code dst}, possibly zero.
      * @throws NullPointerException
-     *             If {@code dst} is {@code null}.
+     *             if {@code dst} is {@code null}.
      * @throws IllegalArgumentException
-     *              If {@code skip} is negative.
+     *              if {@code skip} is negative.
      * @throws UnavailableDeviceException
-     *             If this device is not currently available - such as it is locked by another
+     *             if this device is not currently available - such as it is locked by another
      *             application.
      * @throws ClosedDeviceException
-     *             If the device has been closed.
+     *             if the device has been closed.
      * @throws IOException
-     *             If some other I/O error occurs
+     *             if some other I/O error occurs (e.g. a <em>NACK</em> from the slave device was received).
      */
     int read(int skip, ByteBuffer dst) throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
@@ -255,9 +247,9 @@
      * is the buffer's position at the moment this method is invoked. Upon return the buffer's
      * position will be equal to <i>{@code p + n}</i>; its limit will not have changed.
      * <p />
-     * A read operation will block until the requested <i>r</i> bytes are read or an error occurs.
+     * A read operation will block until the requested <i>r</i> bytes are read.
      * <p />
-     * This method may be invoked at any time. If another thread has already initiated a read
+     * This method may be invoked at any time. If another thread has already initiated a read or write
      * operation upon this slave device, however, then an invocation of this method will block until
      * the first operation is complete.
      *
@@ -266,18 +258,17 @@
      * @param subaddressSize
      *            the slave device's subaddress or register address size (1-4 bytes).
      * @param dst
-     *            The buffer into which bytes are to be transferred
-     * @return The number of bytes read into {@code dst}, possibly zero, or {@code -1} if the device has reached
-     *         end-of-stream
+     *            the buffer into which bytes are to be transferred.
+     * @return the number of bytes read into {@code dst}, possibly zero.
      * @throws NullPointerException
-     *             If {@code dst} is {@code null}.
+     *             if {@code dst} is {@code null}.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
      * @throws ClosedDeviceException
      *             if the device has been closed.
      * @throws IOException
-     *             If some other I/O error occurs
+     *             if some other I/O error occurs (e.g. a <em>NACK</em> from the slave device was received).
      * @throws IllegalArgumentException
      *             if {@code subaddress} is negative or {@code subaddressSize} is not between
      *             {@code 1} and {@code 4}.
@@ -300,9 +291,9 @@
      * is the buffer's position at the moment this method is invoked. Upon return the buffer's
      * position will be equal to <i>{@code p + n}</i>; its limit will not have changed.
      * <p />
-     * A read operation will block until the requested <i>r</i> bytes are read or an error occurs.
+     * A read operation will block until the requested <i>r</i> bytes are read.
      * <p />
-     * This method may be invoked at any time. If another thread has already initiated a read
+     * This method may be invoked at any time. If another thread has already initiated a read or write
      * operation upon this slave device, however, then an invocation of this method will block until
      * the first operation is complete.
      *
@@ -314,18 +305,17 @@
      *            the number of read bytes that must be ignored/skipped before filling in the
      *            {@code dst} buffer.
      * @param dst
-     *            The buffer into which bytes are to be transferred
-     * @return The number of bytes read into {@code dst}, possibly zero, or {@code -1} if the device has reached
-     *         end-of-stream
+     *            the buffer into which bytes are to be transferred.
+     * @return the number of bytes read into {@code dst}, possibly zero.
      * @throws NullPointerException
-     *             If {@code dst} is {@code null}.
+     *             if {@code dst} is {@code null}.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
      * @throws ClosedDeviceException
      *             if the device has been closed.
      * @throws IOException
-     *             If some other I/O error occurs
+     *             if some other I/O error occurs (e.g. a <em>NACK</em> from the slave device was received).
      * @throws IllegalArgumentException
      *             if {@code skip} or {@code subaddress} is negative or {@code subaddressSize} is not between
      *             {@code 1} and {@code 4}.
@@ -336,20 +326,34 @@
     /**
      * Writes a sequence of bytes to this slave device from the given buffer.
      * <p />
-     * {@inheritDoc}
+     * An attempt is made to write up to <i>r</i> bytes to the device, where <i>r</i> is the number
+     * of bytes remaining in the buffer, that is, {@code src.remaining()}, at the moment this method
+     * is invoked.
+     * <p />
+     * Suppose that a byte sequence of length <i>n</i> is written, where <i>{@code 0 <= n <= r}</i>.
+     * This byte sequence will be transferred from the buffer starting at index <i>p</i>, where
+     * <i>p</i> is the buffer's position at the moment this method is invoked; the index of the last
+     * byte written will be <i>{@code p + n - 1}</i>. Upon return the buffer's position will be
+     * equal to <i>{@code p + n}</i>; its limit will not have changed.
+     * <p />
+     * A write operation will return only after writing all of the <i>r</i> requested bytes.
+     * <p />
+     * This method may be invoked at any time. If another thread has already initiated a read or write
+     * operation upon this slave device, however, then an invocation of this method will block until
+     * the first operation is complete.
      *
      * @param src
-     *            The buffer from which bytes are to be retrieved
-     * @return The number of bytes written from {@code src}, possibly zero
+     *            the buffer from which bytes are to be retrieved.
+     * @return the number of bytes written from {@code src}, possibly zero.
      * @throws NullPointerException
-     *             If {@code src} is {@code null}.
+     *             if {@code src} is {@code null}.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
      * @throws ClosedDeviceException
      *             if the device has been closed.
      * @throws IOException
-     *             If some other I/O error occurs
+     *             if some other I/O error occurs (e.g. a <em>NACK</em> from the slave device was received).
      */
     @Override
     int write(ByteBuffer src) throws IOException, UnavailableDeviceException, ClosedDeviceException;
@@ -357,16 +361,20 @@
     /**
      * Writes one byte to this slave device. The eight low-order bits of the argument {@code data}
      * are written. The 24 high-order bits of {@code srcData} are ignored.
+     * <p />
+     * This method may be invoked at any time. If another thread has already initiated a read or write
+     * operation upon this slave device, however, then an invocation of this method will block until
+     * the first operation is complete.
      *
      * @param srcData
-     *            the byte to be written
+     *            the byte to be written.
      * @throws IOException
-     *             if an I/O error occurred
+     *             if an I/O error occurred.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
      * @throws ClosedDeviceException
-     *             if the device has been closed.
+     *             if some other I/O error occurs (e.g. a <em>NACK</em> from the slave device was received).
      */
     void write(int srcData) throws IOException, UnavailableDeviceException, ClosedDeviceException;
 
@@ -387,7 +395,7 @@
      * <p />
      * A write operation will return only after writing all of the <i>r</i> requested bytes.
      * <p />
-     * This method may be invoked at any time. If another thread has already initiated a write
+     * This method may be invoked at any time. If another thread has already initiated a read or write
      * operation upon this slave device, however, then an invocation of this method will block until
      * the first operation is complete.
      *
@@ -396,17 +404,17 @@
      * @param subaddressSize
      *            the slave device's subaddress or register address size (1-4 bytes).
      * @param src
-     *            The buffer from which bytes are to be retrieved
-     * @return The number of bytes written from {@code src}, possibly zero
+     *            the buffer from which bytes are to be retrieved.
+     * @return the number of bytes written from {@code src}, possibly zero.
      * @throws NullPointerException
-     *             If {@code src} is {@code null}.
+     *             if {@code src} is {@code null}.
      * @throws UnavailableDeviceException
      *             if this device is not currently available - such as it is locked by another
      *             application.
      * @throws ClosedDeviceException
      *             if the device has been closed.
      * @throws IOException
-     *             If some other I/O error occurs
+     *             if some other I/O error occurs (e.g. a <em>NACK</em> from the slave device was received).
      * @throws IllegalArgumentException
      *             if {@code subaddress} is negative or {@code subaddressSize} is not between
      *             {@code 1} and {@code 4}.
--- a/src/share/classes/jdk/dio/i2cbus/package-info.java	Mon Jan 26 17:34:34 2015 +0300
+++ b/src/share/classes/jdk/dio/i2cbus/package-info.java	Wed Jan 28 13:51:47 2015 +0400
@@ -62,7 +62,7 @@
  * <pre>
  * slave.close();
  * </pre>
- * </blockquote> The following samples code give 2 examples of using the I2C API to communicate with
+ * </blockquote> The following sample code gives an example of using the I2C API to communicate with
  * an I2C slave device: <blockquote>
  *
  * <pre>
@@ -93,22 +93,7 @@
  *     // handle exception
  * }
  * </pre>
- * </blockquote> Or, <blockquote>
- *
- * <pre>
- * try (I2CDevice slave = DeviceManager.open("EEPROM", I2CDevice.class, (String) null)) {
- *     try {
- *         byte[] addr = new byte[]{/* Some address * /};
- *         ByteBuffer data = ByteBuffer.allocateDirect(4);
- *         slave.begin();
- *         slave.write(ByteBuffer.wrap(addr)); // Writes the address
- *         int count = slave.read(data); // Read the data at that EEPROM address
- *     } finally {
- *         slave.end();
- *     }
- * }
- * </pre>
- * </blockquote> The preceding examples are using a <em>try-with-resources</em> statement;
+ * </blockquote> The preceding example is using a <em>try-with-resources</em> statement;
  * the {@link jdk.dio.i2cbus.I2CDevice#close I2CDevice.close} method is
  * automatically invoked by the platform at the end of the statement.
  * <p />