Page MenuHomeFreeBSD

D59079.diff
No OneTemporary

D59079.diff

diff --git a/sys/dev/sound/pci/hdsp-pcm.c b/sys/dev/sound/pci/hdsp-pcm.c
--- a/sys/dev/sound/pci/hdsp-pcm.c
+++ b/sys/dev/sound/pci/hdsp-pcm.c
@@ -676,10 +676,13 @@
struct sc_pcminfo *scp;
struct sc_chinfo *ch;
struct sc_info *sc;
+ struct pcmchan_caps *caps;
+ uint32_t *data;
int num;
scp = devinfo;
sc = scp->sc;
+ caps = malloc(sizeof(struct pcmchan_caps), M_HDSP, M_WAITOK);
mtx_lock(&sc->lock);
num = scp->chnum;
@@ -704,7 +707,7 @@
SND_FORMAT(AFMT_S32_LE, hdsp_port_slot_count(ch->ports, 192000), 0);
ch->cap_fmts[3] = 0;
- ch->caps = malloc(sizeof(struct pcmchan_caps), M_HDSP, M_NOWAIT);
+ ch->caps = caps;
*(ch->caps) = (struct pcmchan_caps) {32000, 192000, ch->cap_fmts, 0};
/* HDSP 9652 does not support quad speed sample rates. */
@@ -715,7 +718,6 @@
/* Allocate maximum buffer size. */
ch->size = HDSP_CHANBUF_SIZE * hdsp_port_slot_count_max(ch->ports);
- ch->data = malloc(ch->size, M_HDSP, M_NOWAIT);
ch->position = 0;
ch->buffer = b;
@@ -726,6 +728,17 @@
mtx_unlock(&sc->lock);
+ /*
+ * It is safe to access ch->size here without holding the lock, because
+ * 1) as of now, ch->size is written only once, here, and 2) ch's
+ * lifetime is equal to scp's lifetime so it cannot go away yet.
+ */
+ data = malloc(ch->size, M_HDSP, M_WAITOK);
+
+ mtx_lock(&sc->lock);
+ ch->data = data;
+ mtx_unlock(&sc->lock);
+
if (sndbuf_setup(ch->buffer, ch->data, ch->size) != 0) {
device_printf(scp->dev, "Can't setup sndbuf.\n");
hdspchan_free(obj, ch);
diff --git a/sys/dev/sound/pci/hdspe-pcm.c b/sys/dev/sound/pci/hdspe-pcm.c
--- a/sys/dev/sound/pci/hdspe-pcm.c
+++ b/sys/dev/sound/pci/hdspe-pcm.c
@@ -670,10 +670,13 @@
struct sc_pcminfo *scp;
struct sc_chinfo *ch;
struct sc_info *sc;
+ struct pcmchan_caps *caps;
+ uint32_t *data;
int num;
scp = devinfo;
sc = scp->sc;
+ caps = malloc(sizeof(struct pcmchan_caps), M_HDSPE, M_WAITOK);
mtx_lock(&sc->lock);
num = scp->chnum;
@@ -697,12 +700,11 @@
ch->cap_fmts[2] =
SND_FORMAT(AFMT_S32_LE, hdspe_channel_count(ch->ports, 8), 0);
ch->cap_fmts[3] = 0;
- ch->caps = malloc(sizeof(struct pcmchan_caps), M_HDSPE, M_NOWAIT);
+ ch->caps = caps;
*(ch->caps) = (struct pcmchan_caps) {32000, 192000, ch->cap_fmts, 0};
/* Allocate maximum buffer size. */
ch->size = HDSPE_CHANBUF_SIZE * hdspe_channel_count(ch->ports, 8);
- ch->data = malloc(ch->size, M_HDSPE, M_NOWAIT);
ch->position = 0;
ch->buffer = b;
@@ -713,6 +715,17 @@
mtx_unlock(&sc->lock);
+ /*
+ * It is safe to access ch->size here without holding the lock, because
+ * 1) as of now, ch->size is written only once, here, and 2) ch's
+ * lifetime is equal to scp's lifetime so it cannot go away yet.
+ */
+ data = malloc(ch->size, M_HDSPE, M_WAITOK);
+
+ mtx_lock(&sc->lock);
+ ch->data = data;
+ mtx_unlock(&sc->lock);
+
if (sndbuf_setup(ch->buffer, ch->data, ch->size) != 0) {
device_printf(scp->dev, "Can't setup sndbuf.\n");
hdspechan_free(obj, ch);

File Metadata

Mime Type
text/plain
Expires
Sun, Aug 23, 1:45 PM (4 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37141819
Default Alt Text
D59079.diff (2 KB)

Event Timeline