Bug 201021

Summary: ALSA bebob driver often can't take bootloader to run firmware even if sending cue
Product: Drivers Reporter: Takashi Sakamoto (o-takashi)
Component: Sound(ALSA)Assignee: Jaroslav Kysela (perex)
Status: RESOLVED CODE_FIX    
Severity: normal CC: o-takashi
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: at least v3.16 or later Subsystem:
Regression: Yes Bisected commit-id:

Description Takashi Sakamoto 2018-09-05 11:04:16 UTC
With recent Linux kernel, snd-bebob often fail to take bootloader to run runtime firmware for supported M-Audio models.
(FireWire Audiophile, 410, 1804)

```
$ echo 1 > /sys/module/firewire_ohci/parameters/debug
(connect the device to IEEE 1394 bus and autoload snd-bebob)
$ journalctl -n 10
...
[12748.022203] firewire_ohci 0000:02:00.0: AT spd 2 tl 09, ffc1 -> ffc0, ack_pending , BR req, ffffc8020020 8,0
[12748.022305] firewire_ohci 0000:02:00.0: AR spd 0 tl 09, ffc0 -> ffc1, ack_complete, BR resp 8,31
[12748.022366] firewire_ohci 0000:02:00.0: AT spd 2 tl 0a, ffc1 -> ffc0, ack_pending , BW req, ffffc8021000 c,0
[12748.022482] firewire_ohci 0000:02:00.0: AR spd 0 tl 0a, ffc0 -> ffc1, ack_complete, W resp
[12748.022523] firewire_core 0000:02:00.0: created device fw1: GUID 000d6c01100af510, S400
...
(no bus reset occurs)
$ cat /sys/bus/firewire/devices/fw1.0/model_name
FW Bootloader
```

When handy transferring the cue, I can successfully run the runtime firmware.

``
$ firewire-request /dev/fw1 write  0xffffc8021000 0x010000000000110100000000
$ journalctl
...
Sep 05 19:30:19 workstation kernel: firewire_ohci 0000:02:00.0: AT spd 2 tl 17, ffc1 -> ffc0, ack_pending , BW req, ffffc8021000 c,0
Sep 05 19:30:19 workstation kernel: firewire_ohci 0000:02:00.0: AR spd 0 tl 17, ffc0 -> ffc1, ack_complete, W resp
Sep 05 19:30:52 workstation kernel: firewire_ohci 0000:02:00.0: AT spd 2 tl 18, ffc1 -> ffc0, ack_pending , BW req, ffffc8021000 c,0
Sep 05 19:30:52 workstation kernel: firewire_ohci 0000:02:00.0: AR spd 0 tl 18, ffc0 -> ffc1, ack_complete, W resp
Sep 05 19:30:55 workstation kernel: firewire_ohci 0000:02:00.0: AR evt_bus_reset, generation 14
Sep 05 19:30:55 workstation kernel: firewire_core 0000:02:00.0: phy config: new root=ffc1, gap_count=5
Sep 05 19:30:55 workstation kernel: firewire_ohci 0000:02:00.0: AT ack_complete, PHY 01c50000 fe3affff
Sep 05 19:30:55 workstation kernel: firewire_ohci 0000:02:00.0: AR evt_bus_reset, generation 15
Sep 05 19:30:55 workstation kernel: firewire_ohci 0000:02:00.0: AR ack_complete, PHY 01040300 fefbfcff
Sep 05 19:30:55 workstation kernel: firewire_ohci 0000:02:00.0: AR ack_complete, PHY 010c03e2 fef3fc1d
Sep 05 19:30:55 workstation kernel: firewire_ohci 0000:02:00.0: AR ack_complete, PHY 01141100 feebeeff
Sep 05 19:30:55 workstation kernel: firewire_ohci 0000:02:00.0: AR ack_complete, PHY 011c1140 fee3eebf
Sep 05 19:30:56 workstation kernel: firewire_ohci 0000:02:00.0: AT spd 2 tl 23, ffc1 -> ffc0, ack_pending , QR req, fffff0000400
Sep 05 19:30:56 workstation kernel: firewire_ohci 0000:02:00.0: AR spd 2 tl 23, ffc0 -> ffc1, ack_complete, QR resp = 0429f1f7
```

I suspect that this is timing issue but not cleared yet.

This issue is reported in below forums:
 - https://forum.manjaro.org/t/firewire-m-audio-410-driver-wont-load-firmware/51165.
 - https://github.com/takaswie/snd-firewire-improve/issues/22
Comment 1 Takashi Sakamoto 2018-09-06 12:45:56 UTC
My protocol analyzer of IEEE 1394 bus record below entry for the cue from snd-bebob in Ubuntu 18.10 (4.18.0-7-generic) on AMD Ryzen 5 2400G.

```
rel. time (uSec),type,source ID,dest. ID,offset,label,retry code,response code,priority,data length,quadlet data,tag,channel,sync.,speed,acknowledge,data
0.000,WriteBlockReq,0xFFC2,0xFFC1,0xFFFFC8021000,23,retry_X,,0,12,,,,,400,ack_pending,0x134F6737,0x174F273B,0xB3DD570C,0xB7D632ED
```

The transaction includes unexpected content of payload:
 - expected: 0x01000000,0x00001101,0x00000000
 - actual:   0x134F6737,0x174F273B,0xB3DD570C

This transaction is executed in below code of 'sound/firewire/bebob/bebob_maudio.c'.


```
 94 int snd_bebob_maudio_load_firmware(struct fw_unit *unit)
 95 {
 96         struct fw_device *device = fw_parent_device(unit);
 97         int err, rcode;
 98         u64 date;
 99         __le32 cues[3] = {
100                 cpu_to_le32(MAUDIO_BOOTLOADER_CUE1),
101                 cpu_to_le32(MAUDIO_BOOTLOADER_CUE2),
102                 cpu_to_le32(MAUDIO_BOOTLOADER_CUE3)
103         };
104 
105         /* check date of software used to build */
106         err = snd_bebob_read_block(unit, INFO_OFFSET_SW_DATE,
107                                    &date, sizeof(u64));
108         if (err < 0)
109                 goto end;
110         /*      
111          * firmware version 5058 or later has date later than "20070401", but
112          * 'date' is not null-terminated.
113          */
114         if (date < 0x3230303730343031LL) {
115                 dev_err(&unit->device,
116                         "Use firmware version 5058 or later\n");
117                 err = -ENOSYS;     
118                 goto end;
119         }       
120         
121         rcode = fw_run_transaction(device->card, TCODE_WRITE_BLOCK_REQUEST,
122                                    device->node_id, device->generation,
123                                    device->max_speed, BEBOB_ADDR_REG_REQ,
124                                    cues, sizeof(cues));
125         if (rcode != RCODE_COMPLETE) {
126                 dev_err(&unit->device,
127                         "Failed to send a cue to load firmware\n");
128                 err = -EIO;
129         }
130 end:
131         return err;
132 }                                  
```

If the data of 'cues' is in kernel stack, the cause is enabled 'CONFIG_VMAP_STACK'[1] introduced in v4.9 kernel because 7th argument of 'fw_run_transaction()' is passed as a 2nd argument of 'dma_map_single()' in 'at_context_queue_packet()' of 'drivers/firewire/ohci.c'.

[1] https://lwn.net/Articles/692208/
Comment 2 Takashi Sakamoto 2018-09-10 13:27:23 UTC
A fix was applied to sound tree.
https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git/commit/?id=493626f2d87a74e6dbea1686499ed6e7e600484e

This will be pulled into v4.20 kernel.