Created attachment 273303 [details] swapped busdma sync operations in the DMA_TO_DEVICE / DMA_FROM_DEVICE LinuxKPI: fix swapped busdma sync ops in DMA_TO_DEVICE/FROM_DEVICE PRE-sync dma_sync_single_for_device() and the PRE-sync switch in linux_dma_map_sg_attrs() transpose the busdma sync operations for the DMA_TO_DEVICE and DMA_FROM_DEVICE directions. Per the Linux DMA API, dma_sync_single_for_device() on a DMA_TO_DEVICE mapping must make the CPU's writes visible to the device before it reads the buffer. For a bounce buffer that means copying the client buffer into the bounce page, which busdma performs on BUS_DMASYNC_PREWRITE (see bounce_bus_dmamap_sync() in sys/x86/x86/busdma_bounce.c: PREWRITE does bcopy(client -> bounce); PREREAD moves no data). The code instead issued BUS_DMASYNC_PREREAD for DMA_TO_DEVICE (a no-op) and BUS_DMASYNC_PREWRITE for DMA_FROM_DEVICE. The bug is only observable when a streaming mapping actually bounces, i.e. a device with a sub-64-bit DMA mask on a machine with RAM above the mask limit. Most LinuxKPI drivers use a 64-bit mask and never bounce, so the wrong op was a harmless no-op. ath10k(4) (QCA6174) forces a 32-bit mask via dma_set_mask_and_coherent(DMA_BIT_MASK(32)); on a >4GB machine its BMI request buffer (DMA_TO_DEVICE) is never copied into the bounce page, the target never sees the command, and firmware probe fails with: ath10k0: bmi cmd took 3009 jiffies hz 1000 ret -60 ath10k0: could not get target info (-60) ath10k0: could not probe fw (-60) Capping physmem below 4GB (no bounce) or applying this patch both resolve it; with the patch ath10k attaches and scans normally at full 16GB. The POST-sync paths (dma_sync_single_for_cpu(), linux_dma_unmap_sg_attrs()) already use the conventional DMA_TO_DEVICE->POSTWRITE / DMA_FROM_DEVICE->POSTREAD mapping; only the two PRE switches were swapped. This change makes PRE match. DMA_BIDIRECTIONAL (PREWRITE) is unchanged.