*      reset, but then cleared when the units are ready again, which
         *      happens immediately for us.
         */
-       return 0;
+       u32 value = 0x0000;
+
+       /* Bit 8 (cmstr): */
+       value |= card->driver->read_csr_reg(card, CSR_STATE_CLEAR);
+
+       return value;
 }
 
 static void update_split_timeout(struct fw_card *card)
                if (tcode == TCODE_READ_QUADLET_REQUEST) {
                        *data = cpu_to_be32(read_state_register(card));
                } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
+                       card->driver->write_csr_reg(card, CSR_STATE_CLEAR,
+                                                   be32_to_cpu(*data));
                } else {
                        rcode = RCODE_TYPE_ERROR;
                }
                if (tcode == TCODE_READ_QUADLET_REQUEST) {
                        *data = cpu_to_be32(read_state_register(card));
                } else if (tcode == TCODE_WRITE_QUADLET_REQUEST) {
-                       /* FIXME: implement cmstr */
+                       card->driver->write_csr_reg(card, CSR_STATE_SET,
+                                                   be32_to_cpu(*data));
                        /* FIXME: implement abdicate */
                } else {
                        rcode = RCODE_TYPE_ERROR;
 
        unsigned quirks;
        unsigned int pri_req_max;
        u32 bus_time;
+       bool is_root;
 
        /*
         * Spinlock for accessing fw_ohci data.  Never call out of
        unsigned long flags;
        void *free_rom = NULL;
        dma_addr_t free_rom_bus = 0;
+       bool is_new_root;
 
        reg = reg_read(ohci, OHCI1394_NodeID);
        if (!(reg & OHCI1394_NodeID_idValid)) {
        ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
                               OHCI1394_NodeID_nodeNumber);
 
+       is_new_root = (reg & OHCI1394_NodeID_root) != 0;
+       if (!(ohci->is_root && is_new_root))
+               reg_write(ohci, OHCI1394_LinkControlSet,
+                         OHCI1394_LinkControl_cycleMaster);
+       ohci->is_root = is_new_root;
+
        reg = reg_read(ohci, OHCI1394_SelfIDCount);
        if (reg & OHCI1394_SelfIDCount_selfIDError) {
                fw_notify("inconsistent self IDs\n");
        u32 value;
 
        switch (csr_offset) {
+       case CSR_STATE_CLEAR:
+       case CSR_STATE_SET:
+               /* the controller driver handles only the cmstr bit */
+               if (ohci->is_root &&
+                   (reg_read(ohci, OHCI1394_LinkControlSet) &
+                    OHCI1394_LinkControl_cycleMaster))
+                       return CSR_STATE_BIT_CMSTR;
+               else
+                       return 0;
+
        case CSR_NODE_IDS:
                return reg_read(ohci, OHCI1394_NodeID) << 16;
 
        unsigned long flags;
 
        switch (csr_offset) {
+       case CSR_STATE_CLEAR:
+               /* the controller driver handles only the cmstr bit */
+               if ((value & CSR_STATE_BIT_CMSTR) && ohci->is_root) {
+                       reg_write(ohci, OHCI1394_LinkControlClear,
+                                 OHCI1394_LinkControl_cycleMaster);
+                       flush_writes(ohci);
+               }
+               break;
+
+       case CSR_STATE_SET:
+               if ((value & CSR_STATE_BIT_CMSTR) && ohci->is_root) {
+                       reg_write(ohci, OHCI1394_LinkControlSet,
+                                 OHCI1394_LinkControl_cycleMaster);
+                       flush_writes(ohci);
+               }
+               break;
+
        case CSR_NODE_IDS:
                reg_write(ohci, OHCI1394_NodeID, value >> 16);
                flush_writes(ohci);
 
 #define   OHCI1394_LinkControl_cycleSource     (1 << 22)
 #define OHCI1394_NodeID                       0x0E8
 #define   OHCI1394_NodeID_idValid             0x80000000
+#define   OHCI1394_NodeID_root                0x40000000
 #define   OHCI1394_NodeID_nodeNumber          0x0000003f
 #define   OHCI1394_NodeID_busNumber           0x0000ffc0
 #define OHCI1394_PhyControl                   0x0EC