diff --git a/TODO b/TODO
index 8ee1b2beeee105e3845e1a5bd813a969d020a26a..92089a8b6e843764eb98f7ee52bd1bfd94a342b3 100644
--- a/TODO
+++ b/TODO
@@ -8,12 +8,11 @@ $Id$
 
 Version 1.4.0:
 
-* Slaves as array.
 * Replace all Sysfs files via the new ethercat tool.
     - Slave alias write
-    - Slave SII write
     - Slave info (flags, mailbox, general) 
     - Config info (alias, position, type, Pdos, Sdos)
+* Slaves as array.
 * Remove the end state of the master state machine.
 * Supply new ec_master_state_t.
 * Implement ecrt_slave_config_state().
diff --git a/master/cdev.c b/master/cdev.c
index 2baf654149e6d5a2b1364cfa8f8bcc8b4f4540b1..907f748a822abc7dbbdbf02b2b3636b367e512cd 100644
--- a/master/cdev.c
+++ b/master/cdev.c
@@ -196,6 +196,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
                 data.sync_count = slave->sii.sync_count;
                 data.sdo_count = ec_slave_sdo_count(slave);
+                data.sii_nwords = slave->sii_nwords;
 
                 if (slave->sii.name) {
                     strncpy(data.name, slave->sii.name,
@@ -760,6 +761,40 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                 break;
             }
 
+        case EC_IOCTL_SII_READ:
+            {
+                ec_ioctl_sii_read_t data;
+                const ec_slave_t *slave;
+
+                if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+                    retval = -EFAULT;
+                    break;
+                }
+                
+                if (!(slave = ec_master_find_slave(
+                                master, 0, data.slave_position))) {
+                    EC_ERR("Slave %u does not exist!\n", data.slave_position);
+                    retval = -EINVAL;
+                    break;
+                }
+
+                if (!data.nwords
+                        || data.offset + data.nwords > slave->sii_nwords) {
+                    EC_ERR("Invalid SII read offset/size %u/%u for slave "
+                            "SII size %u!\n", data.offset,
+                            data.nwords, slave->sii_nwords);
+                    retval = -EINVAL;
+                    break;
+                }
+
+                if (copy_to_user((void __user *) data.words,
+                            slave->sii_words + data.offset, data.nwords * 2)) {
+                    retval = -EFAULT;
+                    break;
+                }
+                break;
+            }
+
         default:
             retval = -ENOTTY;
     }
diff --git a/master/ioctl.h b/master/ioctl.h
index 94b6ba77c01b6243b1c87c15bf51082d8e9aca62..ed7db26241dd6a214d39d0ef17756c3167413263 100644
--- a/master/ioctl.h
+++ b/master/ioctl.h
@@ -67,23 +67,24 @@
 #define EC_IOCTL_SDO_ENTRY    EC_IOWR(0x0c, ec_ioctl_sdo_entry_t)
 #define EC_IOCTL_SDO_UPLOAD   EC_IOWR(0x0d, ec_ioctl_sdo_upload_t)
 #define EC_IOCTL_SDO_DOWNLOAD  EC_IOW(0x0e, ec_ioctl_sdo_download_t)
+#define EC_IOCTL_SII_READ     EC_IOWR(0x0f, ec_ioctl_sii_read_t)
 
 /*****************************************************************************/
 
 typedef struct {
-    unsigned int slave_count;
+    uint32_t slave_count;
     uint8_t mode;
     struct {
         uint8_t address[6];
         uint8_t attached;
-        unsigned int tx_count;
-        unsigned int rx_count;
+        uint32_t tx_count;
+        uint32_t rx_count;
     } devices[2];
 } ec_ioctl_master_t;
 
 /*****************************************************************************/
 
-#define EC_IOCTL_SLAVE_NAME_SIZE 104
+#define EC_IOCTL_SLAVE_NAME_SIZE 100
 
 typedef struct {
     // input
@@ -98,6 +99,7 @@ typedef struct {
     uint8_t state;
     uint8_t sync_count;
     uint16_t sdo_count;
+    uint32_t sii_nwords;
     char name[EC_IOCTL_SLAVE_NAME_SIZE];
 } ec_ioctl_slave_t;
 
@@ -106,7 +108,7 @@ typedef struct {
 typedef struct {
     // inputs
     uint16_t slave_position;
-    unsigned int sync_index;
+    uint32_t sync_index;
 
     // outputs
     uint16_t physical_start_address;
@@ -124,8 +126,8 @@ typedef struct {
 typedef struct {
     // inputs
     uint16_t slave_position;
-    unsigned int sync_index;
-    unsigned int pdo_pos;
+    uint32_t sync_index;
+    uint32_t pdo_pos;
 
     // outputs
     uint8_t dir;
@@ -141,9 +143,9 @@ typedef struct {
 typedef struct {
     // inputs
     uint16_t slave_position;
-    unsigned int sync_index;
-    unsigned int pdo_pos;
-    unsigned int entry_pos;
+    uint32_t sync_index;
+    uint32_t pdo_pos;
+    uint32_t entry_pos;
 
     // outputs
     uint16_t index;
@@ -156,37 +158,37 @@ typedef struct {
 
 typedef struct {
     // inputs
-	unsigned int index;
+	uint32_t index;
 
     // outputs
-	unsigned int data_size;
+	uint32_t data_size;
 	uint32_t logical_base_address;
 	uint16_t working_counter;
 	uint16_t expected_working_counter;
-    unsigned int fmmu_count;
+    uint32_t fmmu_count;
 } ec_ioctl_domain_t;
 
 /*****************************************************************************/
 
 typedef struct {
     // inputs
-	unsigned int domain_index;
-	unsigned int fmmu_index;
+	uint32_t domain_index;
+	uint32_t fmmu_index;
 
     // outputs
     uint16_t slave_config_alias;
     uint16_t slave_config_position;
     uint8_t fmmu_dir;
 	uint32_t logical_address;
-    unsigned int data_size;
+    uint32_t data_size;
 } ec_ioctl_domain_fmmu_t;
 
 /*****************************************************************************/
 
 typedef struct {
     // inputs
-	unsigned int domain_index;
-    unsigned int data_size;
+	uint32_t domain_index;
+    uint32_t data_size;
     unsigned char *target;
 } ec_ioctl_data_t;
 
@@ -236,11 +238,11 @@ typedef struct {
     uint16_t slave_position;
     uint16_t sdo_index;
     uint8_t sdo_entry_subindex;
-    unsigned int target_size;
+    uint32_t target_size;
     uint8_t *target;
 
     // outputs
-    unsigned int data_size;
+    uint32_t data_size;
 } ec_ioctl_sdo_upload_t;
 
 /*****************************************************************************/
@@ -250,10 +252,20 @@ typedef struct {
     uint16_t slave_position;
     uint16_t sdo_index;
     uint8_t sdo_entry_subindex;
-    unsigned int data_size;
+    uint32_t data_size;
     uint8_t *data;
 } ec_ioctl_sdo_download_t;
 
 /*****************************************************************************/
 
+typedef struct {
+    // inputs
+    uint16_t slave_position;
+    uint16_t offset;
+    uint32_t nwords;
+    uint16_t *words;
+} ec_ioctl_sii_read_t;
+
+/*****************************************************************************/
+
 #endif
diff --git a/tools/Master.cpp b/tools/Master.cpp
index c28c232cff4cb4b074ecd5a604d7802fab3899f4..42d5f62cb2b6d79c10844fc643f5d0de977f253c 100644
--- a/tools/Master.cpp
+++ b/tools/Master.cpp
@@ -606,6 +606,47 @@ void Master::sdoUpload(
 
 /****************************************************************************/
 
+void Master::siiRead(int slavePosition)
+{
+    ec_ioctl_sii_read_t data;
+    ec_ioctl_slave_t slave;
+    unsigned int i;
+
+    if (slavePosition < 0) {
+        stringstream err;
+        err << "'sii_read' requires a slave! Please specify --slave.";
+        throw MasterException(err.str());
+    }
+    data.slave_position = slavePosition;
+
+    open(Read);
+
+    getSlave(&slave, slavePosition);
+
+    if (!slave.sii_nwords)
+        return;
+
+    data.offset = 0;
+    data.nwords = slave.sii_nwords;
+    data.words = new uint16_t[data.nwords];
+
+    if (ioctl(fd, EC_IOCTL_SII_READ, &data) < 0) {
+        stringstream err;
+        delete [] data.words;
+        err << "Failed to read SII: " << strerror(errno);
+        throw MasterException(err.str());
+    }
+
+    for (i = 0; i < data.nwords; i++) {
+        uint16_t *w = data.words + i;
+        cout << *(uint8_t *) w << *((uint8_t *) w + 1);
+    }
+
+    delete [] data.words;
+}
+
+/****************************************************************************/
+
 void Master::requestStates(
         int slavePosition,
         const vector<string> &commandArgs
diff --git a/tools/Master.h b/tools/Master.h
index c3f117c96831d812aa96ddcdd01176fa53cc6e51..f41d1935f21a492b45aac1ff5799da814f5374be 100644
--- a/tools/Master.h
+++ b/tools/Master.h
@@ -50,6 +50,7 @@ class Master
         void listSdos(int, bool = false);
         void sdoDownload(int, const string &, const vector<string> &);
         void sdoUpload(int, const string &, const vector<string> &);
+        void siiRead(int);
         void requestStates(int, const vector<string> &);
         void generateXml(int);
 
diff --git a/tools/main.cpp b/tools/main.cpp
index a7773c7b89839c7c2dc293b6b01cd1bedc1087f2..d2be8c2a2475333a9277086c1e59eef7f01671a1 100644
--- a/tools/main.cpp
+++ b/tools/main.cpp
@@ -41,6 +41,7 @@ void printUsage()
         << "  sdos               List Sdo dictionaries." << endl
         << "  sdo_download (sd)  Write an Sdo entry." << endl
         << "  sdo_upload (su)    Read an Sdo entry." << endl
+        << "  sii_read (sr)      Output a slave's SII contents." << endl
         << "  state              Request slave states." << endl
         << "  xml                Generate slave information xmls." << endl
 		<< "Global options:" << endl
@@ -183,6 +184,8 @@ int main(int argc, char **argv)
             master.sdoDownload(slavePosition, dataTypeStr, commandArgs);
         } else if (command == "sdo_upload" || command == "su") {
             master.sdoUpload(slavePosition, dataTypeStr, commandArgs);
+        } else if (command == "sii_read" || command == "sr") {
+            master.siiRead(slavePosition);
         } else if (command == "state") {
             master.requestStates(slavePosition, commandArgs);
         } else if (command == "xml") {