diff options
author | Michal Meloun <mmel@FreeBSD.org> | 2021-10-07 18:42:56 +0000 |
---|---|---|
committer | Michal Meloun <mmel@FreeBSD.org> | 2022-01-20 10:11:17 +0000 |
commit | a5e76683b2deb568381e4468fd5927c7edb401b4 (patch) | |
tree | dae4e7b5ea704d9c691dffc932b10130a012e96c | |
parent | 8e3cc69a4e4a92ba268e9827ba7f74dcaeed93a4 (diff) | |
download | src-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.c | 15 |
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); |