Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: sdio: fix alignment issue in struct sdio_func

Certain 64-bit systems (e.g. Amlogic Meson GX) require buffers to be
used for DMA to be 8-byte-aligned. struct sdio_func has an embedded
small DMA buffer not meeting this requirement.
When testing switching to descriptor chain mode in meson-gx driver
SDIO is broken therefore. Fix this by allocating the small DMA buffer
separately as kmalloc ensures that the returned memory area is
properly aligned for every basic data type.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Tested-by: Helmut Klein <hgkr.klein@gmail.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Heiner Kallweit and committed by
Ulf Hansson
5ef1ecf0 4f7d029b

+12 -2
+11 -1
drivers/mmc/core/sdio_bus.c
··· 267 267 sdio_free_func_cis(func); 268 268 269 269 kfree(func->info); 270 - 270 + kfree(func->tmpbuf); 271 271 kfree(func); 272 272 } 273 273 ··· 281 281 func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL); 282 282 if (!func) 283 283 return ERR_PTR(-ENOMEM); 284 + 285 + /* 286 + * allocate buffer separately to make sure it's properly aligned for 287 + * DMA usage (incl. 64 bit DMA) 288 + */ 289 + func->tmpbuf = kmalloc(4, GFP_KERNEL); 290 + if (!func->tmpbuf) { 291 + kfree(func); 292 + return ERR_PTR(-ENOMEM); 293 + } 284 294 285 295 func->card = card; 286 296
+1 -1
include/linux/mmc/sdio_func.h
··· 53 53 unsigned int state; /* function state */ 54 54 #define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ 55 55 56 - u8 tmpbuf[4]; /* DMA:able scratch buffer */ 56 + u8 *tmpbuf; /* DMA:able scratch buffer */ 57 57 58 58 unsigned num_info; /* number of info strings */ 59 59 const char **info; /* info strings */