From nobody Mon May 06 18:36:31 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4VY99C5GzKz5J2rF; Mon, 06 May 2024 18:36:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4VY99C4mVmz4sGq; Mon, 6 May 2024 18:36:31 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1715020591; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=nzDkZfbkPGnfk26duMjWLd086kQS+52dxlwzdZslwKQ=; b=eA3CqmMnTVr8M2n0fyKBE0+M9MzcZowWVM5ci3+Zj9MtLhJyZt1LsDTjyG9CakNavqZFSt FrPbN1Om0gzWJ9/uReXt2jRzaYiEHFWnqsQhCjrmQKHfIIMmj88S4/nG5Xda25Fv3KYd/U Apol0ur7MR95v6eHTICRiaK3TY34PgMHNpN/Dg4Gu8GvAJSwhgDKZljWrwAGRusxW0QGA5 Lp3wUFYWHsO8mc7HHqBxclgMVFPKGPIMJD8uaK/S+mHu7iqWI0f0znvkCGrqJPs1SfhJBD CvqE91Lk4CnbHT7NYi4+t2WVtGzBFbSVGv2h+EtdVU2RMWiyZIWQIs0zUF3hFA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1715020591; a=rsa-sha256; cv=none; b=kJRg36vFZGCxsHQ6IXg6gbBgysv5LpZX/wSWLYOvqDsCrBbL91Mlf+BXi3CKS5gWVANCdq Q0wYuYqkq47lyVprp85rqqa5dxGPtd6PZNzxuTJqHTgPUlJhSRT8SaPAH4la8+PKzL/b7y S9ZjH8b72mRt/M7X29+wXDPL50rJMxlEsVgW0ozaKtjs2d2UHuY0q1CK6GJJhpxy4wShce Tmv+LXMMevHuOjY6CXew2f44rJ80Cj6MG5VNFZgTTNnJ2FnsoZhBjwFtTLQxB0PBCtn2Ic mgpB0jUZbTmbXf1EgjwZNhBvF1iBAjaoPY5Ib0qHJ0J7jFcxfqPWE0762gGoLg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1715020591; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=nzDkZfbkPGnfk26duMjWLd086kQS+52dxlwzdZslwKQ=; b=ZELqhiNpAcbi9J9pBdoMk/IpaQRDbM+J2c1mU7kRRKBGGsFl2hoAZ7OcUikPE8v5TQ4Vwm o+w97TywY1AW9CgCDFl8mIbQO2/57rvF/PjvcelyCPE/neOVLnqPtJerLIHxblwFSgH40q HSMmC4dEcY3ufbAG/kSXx8fP+RpCQIgky/K0qDJCtdFpS837NVoVVG5CQWIAKln6mBjd4p s9+YWuHUxWEkCVV4F8ndc7CnIc8e3nKCep02/I0BJCEhV+tjb3kY1uEuJcgXWIe9QV5dXf CPfdiPjL06Jp4adJGhmKEhUNodH3eLSQDmvKiPPQX+2nbvyOfRAcVw6mIk1Ajw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4VY99C4MWgz1711; Mon, 6 May 2024 18:36:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 446IaVmm059932; Mon, 6 May 2024 18:36:31 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 446IaVbt059929; Mon, 6 May 2024 18:36:31 GMT (envelope-from git) Date: Mon, 6 May 2024 18:36:31 GMT Message-Id: <202405061836.446IaVbt059929@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Christos Margiolis Subject: git: 2e9962ef5704 - main - sound: Merge pcm_chn_create() and chn_init() List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: christos X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2e9962ef57044b191431fe9228841e1415574d82 Auto-Submitted: auto-generated The branch main has been updated by christos: URL: https://cgit.FreeBSD.org/src/commit/?id=2e9962ef57044b191431fe9228841e1415574d82 commit 2e9962ef57044b191431fe9228841e1415574d82 Author: Christos Margiolis AuthorDate: 2024-05-06 18:26:37 +0000 Commit: Christos Margiolis CommitDate: 2024-05-06 18:26:37 +0000 sound: Merge pcm_chn_create() and chn_init() Follow-up of b3ea087c05d8c75978a302cbb3fa92ce1afa3e49 ("sound: Merge pcm_chn_destroy() and chn_kill()") While here, add device_printf()'s to all failure points. Also fix an existing bug where we'd unlock an already unlocked channel, in case we went to "out" (now "out2") before locking the channel. Sponsored by: The FreeBSD Foundation MFC after: 1 week Reviewed by: dev_submerge.ch Differential Revision: https://reviews.freebsd.org/D44993 --- sys/dev/sound/pcm/channel.c | 167 ++++++++++++++++++++++++++++++++++++++------ sys/dev/sound/pcm/channel.h | 3 +- sys/dev/sound/pcm/sound.c | 114 +----------------------------- sys/dev/sound/pcm/sound.h | 1 - sys/dev/sound/pcm/vchan.c | 2 +- 5 files changed, 151 insertions(+), 136 deletions(-) diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index 859476f212ae..996cb0cb04f7 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -1157,14 +1157,112 @@ chn_reset(struct pcm_channel *c, uint32_t fmt, uint32_t spd) return r; } -int -chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) +struct pcm_channel * +chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, + int dir, int num, void *devinfo) { + struct pcm_channel *c; struct feeder_class *fc; struct snd_dbuf *b, *bs; - int i, ret; + char *dirs, *devname, buf[CHN_NAMELEN]; + int i, ret, direction, rpnum, *pnum, max, type, unit; + PCM_BUSYASSERT(d); + PCM_LOCKASSERT(d); + KASSERT(num >= -1, ("invalid num=%d", num)); + + switch (dir) { + case PCMDIR_PLAY: + dirs = "play"; + direction = PCMDIR_PLAY; + pnum = &d->playcount; + type = SND_DEV_DSPHW_PLAY; + max = SND_MAXHWCHAN; + break; + case PCMDIR_PLAY_VIRTUAL: + dirs = "virtual_play"; + direction = PCMDIR_PLAY; + pnum = &d->pvchancount; + type = SND_DEV_DSPHW_VPLAY; + max = SND_MAXVCHANS; + break; + case PCMDIR_REC: + dirs = "record"; + direction = PCMDIR_REC; + pnum = &d->reccount; + type = SND_DEV_DSPHW_REC; + max = SND_MAXHWCHAN; + break; + case PCMDIR_REC_VIRTUAL: + dirs = "virtual_record"; + direction = PCMDIR_REC; + pnum = &d->rvchancount; + type = SND_DEV_DSPHW_VREC; + max = SND_MAXVCHANS; + break; + default: + device_printf(d->dev, + "%s(): invalid channel direction: %d\n", + __func__, dir); + goto out1; + } + + unit = (num == -1) ? 0 : num; + + if (*pnum >= max || unit >= max) { + device_printf(d->dev, "%s(): unit=%d or pnum=%d >= than " + "max=%d\n", __func__, unit, *pnum, max); + goto out1; + } + + rpnum = 0; + + CHN_FOREACH(c, d, channels.pcm) { + if (c->type != type) + continue; + if (unit == c->unit && num != -1) { + device_printf(d->dev, + "%s(): channel num=%d already allocated\n", + __func__, unit); + goto out1; + } + unit++; + if (unit >= max) { + device_printf(d->dev, + "%s(): chan=%d >= max=%d\n", __func__, unit, max); + goto out1; + } + rpnum++; + } + + if (*pnum != rpnum) { + device_printf(d->dev, + "%s(): pnum screwed: dirs=%s pnum=%d rpnum=%d\n", + __func__, dirs, *pnum, rpnum); + goto out1; + } + + PCM_UNLOCK(d); + c = malloc(sizeof(*c), M_DEVBUF, M_WAITOK | M_ZERO); + c->methods = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO); + c->type = type; + c->unit = unit; + c->pid = -1; + strlcpy(c->comm, CHN_COMM_UNUSED, sizeof(c->comm)); + c->parentsnddev = d; + c->parentchannel = parent; + c->dev = d->dev; + c->trigger = PCMTRIG_STOP; chn_lockinit(c, dir); + devname = dsp_unit2name(buf, sizeof(buf), c); + if (devname == NULL) { + ret = EINVAL; + device_printf(d->dev, "%s(): failed to create channel name", + __func__); + goto out2; + } + snprintf(c->name, sizeof(c->name), "%s:%s:%s", + device_get_nameunit(c->dev), dirs, devname); b = NULL; bs = NULL; @@ -1177,20 +1275,31 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) ret = ENOMEM; b = sndbuf_create(c->dev, c->name, "primary", c); - if (b == NULL) - goto out; + if (b == NULL) { + device_printf(d->dev, "%s(): failed to create hardware buffer\n", + __func__); + goto out2; + } bs = sndbuf_create(c->dev, c->name, "secondary", c); - if (bs == NULL) - goto out; + if (bs == NULL) { + device_printf(d->dev, "%s(): failed to create software buffer\n", + __func__); + goto out2; + } CHN_LOCK(c); ret = EINVAL; fc = feeder_getclass(NULL); - if (fc == NULL) - goto out; - if (chn_addfeeder(c, fc, NULL)) - goto out; + if (fc == NULL) { + device_printf(d->dev, "%s(): failed to get feeder class\n", + __func__); + goto out2; + } + if (chn_addfeeder(c, fc, NULL)) { + device_printf(d->dev, "%s(): failed to add feeder\n", __func__); + goto out2; + } /* * XXX - sndbuf_setup() & sndbuf_resize() expect to be called @@ -1226,12 +1335,17 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) CHN_UNLOCK(c); /* XXX - Unlock for CHANNEL_INIT() malloc() call */ c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction); CHN_LOCK(c); - if (c->devinfo == NULL) - goto out; + if (c->devinfo == NULL) { + device_printf(d->dev, "%s(): NULL devinfo\n", __func__); + goto out2; + } ret = ENOMEM; - if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) - goto out; + if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) { + device_printf(d->dev, "%s(): hardware buffer's size is 0\n", + __func__); + goto out2; + } ret = 0; c->direction = direction; @@ -1251,12 +1365,14 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction) bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_NOWAIT); if (bs->shadbuf == NULL) { ret = ENOMEM; - goto out; + device_printf(d->dev, "%s(): failed to create shadow " + "buffer\n", __func__); + goto out2; } } - -out: - CHN_UNLOCK(c); +out2: + if (CHN_LOCKOWNED(c)) + CHN_UNLOCK(c); if (ret) { if (c->devinfo) { if (CHANNEL_FREE(c->methods, c->devinfo)) @@ -1270,10 +1386,19 @@ out: c->flags |= CHN_F_DEAD; chn_lockdestroy(c); - return ret; + PCM_LOCK(d); + + kobj_delete(c->methods, M_DEVBUF); + free(c, M_DEVBUF); + + return (NULL); } - return 0; + PCM_LOCK(d); + + return (c); +out1: + return (NULL); } void diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h index 698a1186924f..6aca089a7c4d 100644 --- a/sys/dev/sound/pcm/channel.h +++ b/sys/dev/sound/pcm/channel.h @@ -259,7 +259,8 @@ int chn_sync(struct pcm_channel *c, int threshold); int chn_flush(struct pcm_channel *c); int chn_poll(struct pcm_channel *c, int ev, struct thread *td); -int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction); +struct pcm_channel *chn_init(struct snddev_info *d, struct pcm_channel *parent, + kobj_class_t cls, int dir, int num, void *devinfo); void chn_kill(struct pcm_channel *c); void chn_shutdown(struct pcm_channel *c); int chn_release(struct pcm_channel *c); diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index 9d5eaf3f5ad7..cc19d119ac36 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -379,116 +379,6 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, maxautovchans, sysctl_hw_snd_maxautovchans, "I", "maximum virtual channel"); -struct pcm_channel * -pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, int num, void *devinfo) -{ - struct pcm_channel *ch; - int direction, err, rpnum, *pnum, max; - int type, unit; - char *dirs, *devname, buf[CHN_NAMELEN]; - - PCM_BUSYASSERT(d); - PCM_LOCKASSERT(d); - KASSERT(num >= -1, ("invalid num=%d", num)); - - switch (dir) { - case PCMDIR_PLAY: - dirs = "play"; - direction = PCMDIR_PLAY; - pnum = &d->playcount; - type = SND_DEV_DSPHW_PLAY; - max = SND_MAXHWCHAN; - break; - case PCMDIR_PLAY_VIRTUAL: - dirs = "virtual_play"; - direction = PCMDIR_PLAY; - pnum = &d->pvchancount; - type = SND_DEV_DSPHW_VPLAY; - max = SND_MAXVCHANS; - break; - case PCMDIR_REC: - dirs = "record"; - direction = PCMDIR_REC; - pnum = &d->reccount; - type = SND_DEV_DSPHW_REC; - max = SND_MAXHWCHAN; - break; - case PCMDIR_REC_VIRTUAL: - dirs = "virtual_record"; - direction = PCMDIR_REC; - pnum = &d->rvchancount; - type = SND_DEV_DSPHW_VREC; - max = SND_MAXVCHANS; - break; - default: - return (NULL); - } - - unit = (num == -1) ? 0 : num; - - if (*pnum >= max || unit >= max) - return (NULL); - - rpnum = 0; - - CHN_FOREACH(ch, d, channels.pcm) { - if (ch->type != type) - continue; - if (unit == ch->unit && num != -1) { - device_printf(d->dev, - "channel num=%d allocated!\n", unit); - return (NULL); - } - unit++; - if (unit >= max) { - device_printf(d->dev, - "chan=%d > %d\n", unit, max); - return (NULL); - } - rpnum++; - } - - if (*pnum != rpnum) { - device_printf(d->dev, - "%s(): WARNING: pnum screwed : dirs=%s pnum=%d rpnum=%d\n", - __func__, dirs, *pnum, rpnum); - return (NULL); - } - - PCM_UNLOCK(d); - ch = malloc(sizeof(*ch), M_DEVBUF, M_WAITOK | M_ZERO); - ch->methods = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO); - ch->type = type; - ch->unit = unit; - ch->pid = -1; - strlcpy(ch->comm, CHN_COMM_UNUSED, sizeof(ch->comm)); - ch->parentsnddev = d; - ch->parentchannel = parent; - ch->dev = d->dev; - ch->trigger = PCMTRIG_STOP; - devname = dsp_unit2name(buf, sizeof(buf), ch); - if (devname == NULL) { - device_printf(d->dev, "Failed to query device name"); - kobj_delete(ch->methods, M_DEVBUF); - free(ch, M_DEVBUF); - return (NULL); - } - snprintf(ch->name, sizeof(ch->name), "%s:%s:%s", - device_get_nameunit(ch->dev), dirs, devname); - - err = chn_init(ch, devinfo, dir, direction); - PCM_LOCK(d); - if (err) { - device_printf(d->dev, "chn_init(%s) failed: err = %d\n", - ch->name, err); - kobj_delete(ch->methods, M_DEVBUF); - free(ch, M_DEVBUF); - return (NULL); - } - - return (ch); -} - int pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch) { @@ -569,9 +459,9 @@ pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo) PCM_BUSYASSERT(d); PCM_LOCK(d); - ch = pcm_chn_create(d, NULL, cls, dir, -1, devinfo); + ch = chn_init(d, NULL, cls, dir, -1, devinfo); if (!ch) { - device_printf(d->dev, "pcm_chn_create(%s, %d, %p) failed\n", + device_printf(d->dev, "chn_init(%s, %d, %p) failed\n", cls->name, dir, devinfo); PCM_UNLOCK(d); return (ENODEV); diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h index 08aa56cc96f7..09e739ea5c20 100644 --- a/sys/dev/sound/pcm/sound.h +++ b/sys/dev/sound/pcm/sound.h @@ -297,7 +297,6 @@ int pcm_setvchans(struct snddev_info *d, int direction, int newcnt, int num); int pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, pid_t pid, char *comm); -struct pcm_channel *pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, int num, void *devinfo); int pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch); int pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch); diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c index c3bc36d924bd..ccac08891220 100644 --- a/sys/dev/sound/pcm/vchan.c +++ b/sys/dev/sound/pcm/vchan.c @@ -698,7 +698,7 @@ vchan_create(struct pcm_channel *parent, int num) } /* create a new playback channel */ - ch = pcm_chn_create(d, parent, &vchan_class, direction, num, parent); + ch = chn_init(d, parent, &vchan_class, direction, num, parent); if (ch == NULL) { PCM_UNLOCK(d); CHN_LOCK(parent);