#define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e
 #define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE      0x4e617475
 #define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE   0x746e736c
+#define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
 
 struct snd_firewire_event_common {
        unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */
        __u32 message;  /* Digi00x-specific message */
 };
 
+struct snd_firewire_event_motu_notification {
+       unsigned int type;
+       __u32 message;  /* MOTU-specific bits. */
+};
+
 union snd_firewire_event {
        struct snd_firewire_event_common            common;
        struct snd_firewire_event_lock_status       lock_status;
        struct snd_firewire_event_dice_notification dice_notification;
        struct snd_firewire_event_efw_response      efw_response;
        struct snd_firewire_event_digi00x_message   digi00x_message;
+       struct snd_firewire_event_motu_notification motu_notification;
 };
 
 
 
 
        spin_lock_irq(&motu->lock);
 
-       while (!motu->dev_lock_changed) {
+       while (!motu->dev_lock_changed && motu->msg == 0) {
                prepare_to_wait(&motu->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
                spin_unlock_irq(&motu->lock);
                schedule();
                motu->dev_lock_changed = false;
 
                count = min_t(long, count, sizeof(event.lock_status));
+       } else {
+               event.motu_notification.type = SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION;
+               event.motu_notification.message = motu->msg;
+               motu->msg = 0;
+
+               count = min_t(long, count, sizeof(event.motu_notification));
        }
 
        spin_unlock_irq(&motu->lock);
        poll_wait(file, &motu->hwdep_wait, wait);
 
        spin_lock_irq(&motu->lock);
-       if (motu->dev_lock_changed)
+       if (motu->dev_lock_changed || motu->msg)
                events = POLLIN | POLLRDNORM;
        else
                events = 0;
 
                           int generation, unsigned long long offset,
                           void *data, size_t length, void *callback_data)
 {
+       struct snd_motu *motu = callback_data;
+       __be32 *buf = (__be32 *)data;
+       unsigned long flags;
+
+       if (tcode != TCODE_WRITE_QUADLET_REQUEST) {
+               fw_send_response(card, request, RCODE_COMPLETE);
+               return;
+       }
+
+       if (offset != motu->async_handler.offset || length != 4) {
+               fw_send_response(card, request, RCODE_ADDRESS_ERROR);
+               return;
+       }
+
+       spin_lock_irqsave(&motu->lock, flags);
+       motu->msg = be32_to_cpu(*buf);
+       spin_unlock_irqrestore(&motu->lock, flags);
+
        fw_send_response(card, request, RCODE_COMPLETE);
+
+       wake_up(&motu->hwdep_wait);
 }
 
 int snd_motu_transaction_reregister(struct snd_motu *motu)