History

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.

Heiner Kallweit committed 9 years ago

Commit 5ef1ecf1 parent 4f7d0292 files · +12 −2Browse files

Unified · Split

2 files
  1. drivers/mmc/core/sdio_bus.c +11 −1
  2. include/linux/mmc/sdio_func.h +1 −1
drivers/mmc/core/sdio_bus.c+11−1
@@ -267,7 +267,7 @@ static void sdio_release_func(struct device *dev) · 266 unmodified lines
267267 sdio_free_func_cis(func);
268268
269269 kfree(func->info);
270−
270+ kfree(func->tmpbuf);
271271 kfree(func);
272272 }
273273
@@ -282,6 +282,16 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card) · 8 unmodified lines
282282 if (!func)
283283 return ERR_PTR(-ENOMEM);
284284
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+ }
294+
285295 func->card = card;
286296
287297 device_initialize(&func->dev);
include/linux/mmc/sdio_func.h+1−1
@@ -53,7 +53,7 @@ struct sdio_func { · 52 unmodified lines
5353 unsigned int state; /* function state */
5454 #define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */
5555
56− u8 tmpbuf[4]; /* DMA:able scratch buffer */
56+ u8 *tmpbuf; /* DMA:able scratch buffer */
5757
5858 unsigned num_info; /* number of info strings */
5959 const char **info; /* info strings */