aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Meloun <mmel@FreeBSD.org>2021-10-07 18:42:56 +0000
committerMichal Meloun <mmel@FreeBSD.org>2022-01-20 10:11:17 +0000
commita5e76683b2deb568381e4468fd5927c7edb401b4 (patch)
treedae4e7b5ea704d9c691dffc932b10130a012e96c
parent8e3cc69a4e4a92ba268e9827ba7f74dcaeed93a4 (diff)
downloadsrc-a5e76683b2deb568381e4468fd5927c7edb401b4.tar.gz
src-a5e76683b2deb568381e4468fd5927c7edb401b4.zip
dwmmc: Calculate the maximum transaction length correctly.
We should reserve two descriptors (not MMC_SECTORS) for potentially unaligned (so bounced) buffer fragments, one for the starting fragment and one for the ending fragment. Submitted by: kjopek@gmail.com MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D30387 (cherry picked from commit dfb7360222856e7e4f5e0e5564281a25af63319c)
-rw-r--r--sys/dev/mmc/host/dwmmc.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c
index 22cbf647cfa0..f12a03e1c7aa 100644
--- a/sys/dev/mmc/host/dwmmc.c
+++ b/sys/dev/mmc/host/dwmmc.c
@@ -145,6 +145,11 @@ struct idmac_desc {
* second half of page
*/
#define IDMAC_MAX_SIZE 2048
+/*
+ * Busdma may bounce buffers, so we must reserve 2 descriptors
+ * (on start and on end) for bounced fragments.
+ */
+#define DWMMC_MAX_DATA (IDMAC_MAX_SIZE * (IDMAC_DESC_SEGS - 2)) / MMC_SECTOR_SIZE
static void dwmmc_next_operation(struct dwmmc_softc *);
static int dwmmc_setup_bus(struct dwmmc_softc *, int);
@@ -1350,13 +1355,7 @@ dwmmc_read_ivar(device_t bus, device_t child, int which, uintptr_t *result)
*(int *)result = sc->host.caps;
break;
case MMCBR_IVAR_MAX_DATA:
- /*
- * Busdma may bounce buffers, so we must reserve 2 descriptors
- * (on start and on end) for bounced fragments.
- *
- */
- *(int *)result = (IDMAC_MAX_SIZE * IDMAC_DESC_SEGS) /
- MMC_SECTOR_SIZE - 3;
+ *(int *)result = DWMMC_MAX_DATA;
break;
case MMCBR_IVAR_TIMING:
*(int *)result = sc->host.ios.timing;
@@ -1436,7 +1435,7 @@ dwmmc_get_tran_settings(device_t dev, struct ccb_trans_settings_mmc *cts)
cts->host_f_min = sc->host.f_min;
cts->host_f_max = sc->host.f_max;
cts->host_caps = sc->host.caps;
- cts->host_max_data = (IDMAC_MAX_SIZE * IDMAC_DESC_SEGS) / MMC_SECTOR_SIZE;
+ cts->host_max_data = DWMMC_MAX_DATA;
memcpy(&cts->ios, &sc->host.ios, sizeof(struct mmc_ios));
return (0);