From 4642c8c5ea8b468fb2cfb43d4294a77c720b45ca Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Wed, 28 Dec 2016 07:37:26 +0000 Subject: [PATCH] Limit number of stripes supported by HDA codec to maximum number announced by HDA controller. Incorrectly implermented HDA codec may report support for more stripes that HDA controller already have. Due to this, always limit number of enabled stripes by global controller maximum. Reviewed by: mav MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D8922 --- sys/dev/sound/pci/hda/hdaa.c | 3 ++- sys/dev/sound/pci/hda/hdac.c | 3 +++ sys/dev/sound/pci/hda/hdac.h | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/dev/sound/pci/hda/hdaa.c b/sys/dev/sound/pci/hda/hdaa.c index 199679ccb9b2..63bd853edda5 100644 --- a/sys/dev/sound/pci/hda/hdaa.c +++ b/sys/dev/sound/pci/hda/hdaa.c @@ -2130,7 +2130,8 @@ hdaa_channel_start(struct hdaa_chan *ch) uint32_t fmt; fmt = hdaa_stream_format(ch); - ch->stripectl = fls(ch->stripecap & hdaa_allowed_stripes(fmt)) - 1; + ch->stripectl = fls(ch->stripecap & hdaa_allowed_stripes(fmt) & + hda_get_stripes_mask(devinfo->dev)) - 1; ch->sid = HDAC_STREAM_ALLOC(device_get_parent(devinfo->dev), devinfo->dev, ch->dir == PCMDIR_PLAY ? 1 : 0, fmt, ch->stripectl, &ch->dmapos); if (ch->sid <= 0) diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index 22458ea53ef8..6409b555bd06 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -1767,6 +1767,9 @@ hdac_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) case HDA_IVAR_DMA_NOCACHE: *result = (sc->flags & HDAC_F_DMA_NOCACHE) != 0; break; + case HDA_IVAR_STRIPES_MASK: + *result = (1 << (1 << sc->num_sdo)) - 1; + break; default: return (ENOENT); } diff --git a/sys/dev/sound/pci/hda/hdac.h b/sys/dev/sound/pci/hda/hdac.h index 859973b043cf..0849bacb08b4 100644 --- a/sys/dev/sound/pci/hda/hdac.h +++ b/sys/dev/sound/pci/hda/hdac.h @@ -707,6 +707,7 @@ enum hdac_device_ivars { HDA_IVAR_SUBSYSTEM_ID, HDA_IVAR_NODE_TYPE, HDA_IVAR_DMA_NOCACHE, + HDA_IVAR_STRIPES_MASK, }; #define HDA_ACCESSOR(var, ivar, type) \ @@ -723,6 +724,7 @@ HDA_ACCESSOR(subdevice_id, SUBDEVICE_ID, uint16_t); HDA_ACCESSOR(subsystem_id, SUBSYSTEM_ID, uint32_t); HDA_ACCESSOR(node_type, NODE_TYPE, uint8_t); HDA_ACCESSOR(dma_nocache, DMA_NOCACHE, uint8_t); +HDA_ACCESSOR(stripes_mask, STRIPES_MASK, uint8_t); #define PCIS_MULTIMEDIA_HDA 0x03