return err;
 }
 
+static void ff400_handle_midi_msg(struct snd_ff *ff, __le32 *buf, size_t length)
+{
+       int i;
+
+       for (i = 0; i < length / 4; i++) {
+               u32 quad = le32_to_cpu(buf[i]);
+               u8 byte;
+               unsigned int index;
+               struct snd_rawmidi_substream *substream;
+
+               /* Message in first port. */
+               /*
+                * This value may represent the index of this unit when the same
+                * units are on the same IEEE 1394 bus. This driver doesn't use
+                * it.
+                */
+               index = (quad >> 8) & 0xff;
+               if (index > 0) {
+                       substream = READ_ONCE(ff->tx_midi_substreams[0]);
+                       if (substream != NULL) {
+                               byte = quad & 0xff;
+                               snd_rawmidi_receive(substream, &byte, 1);
+                       }
+               }
+
+               /* Message in second port. */
+               index = (quad >> 24) & 0xff;
+               if (index > 0) {
+                       substream = READ_ONCE(ff->tx_midi_substreams[1]);
+                       if (substream != NULL) {
+                               byte = (quad >> 16) & 0xff;
+                               snd_rawmidi_receive(substream, &byte, 1);
+                       }
+               }
+       }
+}
+
 const struct snd_ff_protocol snd_ff_protocol_ff400 = {
+       .handle_midi_msg        = ff400_handle_midi_msg,
        .begin_session          = ff400_begin_session,
        .finish_session         = ff400_finish_session,
        .switch_fetching_mode   = ff400_switch_fetching_mode,
 
 {
        struct snd_ff *ff = callback_data;
        __le32 *buf = data;
-       u32 quad;
-       u8 byte;
-       unsigned int index;
-       struct snd_rawmidi_substream *substream;
-       int i;
 
        fw_send_response(card, request, RCODE_COMPLETE);
 
-       for (i = 0; i < length / 4; i++) {
-               quad = le32_to_cpu(buf[i]);
-
-               /* Message in first port. */
-               /*
-                * This value may represent the index of this unit when the same
-                * units are on the same IEEE 1394 bus. This driver doesn't use
-                * it.
-                */
-               index = (quad >> 8) & 0xff;
-               if (index > 0) {
-                       substream = READ_ONCE(ff->tx_midi_substreams[0]);
-                       if (substream != NULL) {
-                               byte = quad & 0xff;
-                               snd_rawmidi_receive(substream, &byte, 1);
-                       }
-               }
-
-               /* Message in second port. */
-               index = (quad >> 24) & 0xff;
-               if (index > 0) {
-                       substream = READ_ONCE(ff->tx_midi_substreams[1]);
-                       if (substream != NULL) {
-                               byte = (quad >> 16) & 0xff;
-                               snd_rawmidi_receive(substream, &byte, 1);
-                       }
-               }
-       }
+       ff->spec->protocol->handle_midi_msg(ff, buf, length);
 }
 
 static int allocate_own_address(struct snd_ff *ff, int i)
 
 };
 
 struct snd_ff_protocol {
+       void (*handle_midi_msg)(struct snd_ff *ff, __le32 *buf, size_t length);
        int (*begin_session)(struct snd_ff *ff, unsigned int rate);
        void (*finish_session)(struct snd_ff *ff);
        int (*switch_fetching_mode)(struct snd_ff *ff, bool enable);