Deleted Added
full compact
sound.c (124617) sound.c (124740)
1/*
2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
3 * (C) 1997 Luigi Rizzo (luigi@iet.unipi.it)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 13 unchanged lines hidden (view full) ---

22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <dev/sound/pcm/sound.h>
29#include <dev/sound/pcm/vchan.h>
1/*
2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
3 * (C) 1997 Luigi Rizzo (luigi@iet.unipi.it)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 13 unchanged lines hidden (view full) ---

22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <dev/sound/pcm/sound.h>
29#include <dev/sound/pcm/vchan.h>
30#include <dev/sound/pcm/dsp.h>
30#include <sys/sysctl.h>
31
32#include "feeder_if.h"
33
31#include <sys/sysctl.h>
32
33#include "feeder_if.h"
34
34SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/sound.c 124617 2004-01-17 10:37:11Z phk $");
35SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/sound.c 124740 2004-01-20 03:58:57Z matk $");
35
36devclass_t pcm_devclass;
37
38int pcm_veto_load = 1;
39
40#ifdef USING_DEVFS
41int snd_unit = 0;
42TUNABLE_INT("hw.snd.unit", &snd_unit);

--- 365 unchanged lines hidden (view full) ---

408
409 kobj_delete(ch->methods, M_DEVBUF);
410 free(ch, M_DEVBUF);
411
412 return 0;
413}
414
415int
36
37devclass_t pcm_devclass;
38
39int pcm_veto_load = 1;
40
41#ifdef USING_DEVFS
42int snd_unit = 0;
43TUNABLE_INT("hw.snd.unit", &snd_unit);

--- 365 unchanged lines hidden (view full) ---

409
410 kobj_delete(ch->methods, M_DEVBUF);
411 free(ch, M_DEVBUF);
412
413 return 0;
414}
415
416int
416pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev)
417pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch)
417{
418 struct snddev_channel *sce, *tmp, *after;
418{
419 struct snddev_channel *sce, *tmp, *after;
419 int unit = device_get_unit(d->dev);
420 int x = -1;
420 int device = device_get_unit(d->dev);
421
421
422 /*
423 * Note it's confusing nomenclature.
424 * dev_t
425 * device -> pcm_device
426 * unit -> pcm_channel
427 * channel -> snddev_channel
428 * device_t
429 * unit -> pcm_device
430 */
431
422 sce = malloc(sizeof(*sce), M_DEVBUF, M_WAITOK | M_ZERO);
423 if (!sce) {
424 return ENOMEM;
425 }
426
427 snd_mtxlock(d->lock);
428 sce->channel = ch;
432 sce = malloc(sizeof(*sce), M_DEVBUF, M_WAITOK | M_ZERO);
433 if (!sce) {
434 return ENOMEM;
435 }
436
437 snd_mtxlock(d->lock);
438 sce->channel = ch;
439 sce->chan_num= d->devcount++;
429 if (SLIST_EMPTY(&d->channels)) {
430 SLIST_INSERT_HEAD(&d->channels, sce, link);
431 } else {
432 after = NULL;
433 SLIST_FOREACH(tmp, &d->channels, link) {
434 after = tmp;
435 }
436 SLIST_INSERT_AFTER(after, sce, link);
437 }
440 if (SLIST_EMPTY(&d->channels)) {
441 SLIST_INSERT_HEAD(&d->channels, sce, link);
442 } else {
443 after = NULL;
444 SLIST_FOREACH(tmp, &d->channels, link) {
445 after = tmp;
446 }
447 SLIST_INSERT_AFTER(after, sce, link);
448 }
438 if (mkdev)
439 x = d->devcount++;
440 snd_mtxunlock(d->lock);
449 snd_mtxunlock(d->lock);
450 sce->dsp_devt= make_dev(&dsp_cdevsw,
451 PCMMKMINOR(device, SND_DEV_DSP, sce->chan_num),
452 UID_ROOT, GID_WHEEL, 0666, "dsp%d.%d",
453 device, sce->chan_num);
441
454
442 if (mkdev) {
443 dsp_register(unit, x);
444 if (ch->direction == PCMDIR_REC)
445 dsp_registerrec(unit, ch->num);
446 }
455 sce->dspW_devt= make_dev(&dsp_cdevsw,
456 PCMMKMINOR(device, SND_DEV_DSP16, sce->chan_num),
457 UID_ROOT, GID_WHEEL, 0666, "dspW%d.%d",
458 device, sce->chan_num);
447
459
460 sce->audio_devt= make_dev(&dsp_cdevsw,
461 PCMMKMINOR(device, SND_DEV_AUDIO, sce->chan_num),
462 UID_ROOT, GID_WHEEL, 0666, "audio%d.%d",
463 device, sce->chan_num);
464
465 if (ch->direction == PCMDIR_REC)
466 sce->dspr_devt = make_dev(&dsp_cdevsw,
467 PCMMKMINOR(device, SND_DEV_DSPREC,
468 sce->chan_num), UID_ROOT, GID_WHEEL,
469 0666, "dspr%d.%d", device, sce->chan_num);
470
448 return 0;
449}
450
451int
471 return 0;
472}
473
474int
452pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch, int rmdev)
475pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch)
453{
454 struct snddev_channel *sce;
476{
477 struct snddev_channel *sce;
455 int unit = device_get_unit(d->dev);
456#if 0
457 int ourlock;
458
459 ourlock = 0;
460 if (!mtx_owned(d->lock)) {
461 snd_mtxlock(d->lock);
462 ourlock = 1;
463 }

--- 5 unchanged lines hidden (view full) ---

469 }
470#if 0
471 if (ourlock)
472 snd_mtxunlock(d->lock);
473#endif
474 return EINVAL;
475gotit:
476 SLIST_REMOVE(&d->channels, sce, snddev_channel, link);
478#if 0
479 int ourlock;
480
481 ourlock = 0;
482 if (!mtx_owned(d->lock)) {
483 snd_mtxlock(d->lock);
484 ourlock = 1;
485 }

--- 5 unchanged lines hidden (view full) ---

491 }
492#if 0
493 if (ourlock)
494 snd_mtxunlock(d->lock);
495#endif
496 return EINVAL;
497gotit:
498 SLIST_REMOVE(&d->channels, sce, snddev_channel, link);
477 if (rmdev) {
478 dsp_unregister(unit, --d->devcount);
479 if (ch->direction == PCMDIR_REC)
480 dsp_unregisterrec(unit, ch->num);
481 }
482
483 if (ch->direction == PCMDIR_REC)
484 d->reccount--;
485 else if (ch->flags & CHN_F_VIRTUAL)
486 d->vchancount--;
487 else
488 d->playcount--;
489

--- 14 unchanged lines hidden (view full) ---

504 int err;
505
506 ch = pcm_chn_create(d, NULL, cls, dir, devinfo);
507 if (!ch) {
508 device_printf(d->dev, "pcm_chn_create(%s, %d, %p) failed\n", cls->name, dir, devinfo);
509 return ENODEV;
510 }
511
499
500 if (ch->direction == PCMDIR_REC)
501 d->reccount--;
502 else if (ch->flags & CHN_F_VIRTUAL)
503 d->vchancount--;
504 else
505 d->playcount--;
506

--- 14 unchanged lines hidden (view full) ---

521 int err;
522
523 ch = pcm_chn_create(d, NULL, cls, dir, devinfo);
524 if (!ch) {
525 device_printf(d->dev, "pcm_chn_create(%s, %d, %p) failed\n", cls->name, dir, devinfo);
526 return ENODEV;
527 }
528
512 err = pcm_chn_add(d, ch, 1);
529 err = pcm_chn_add(d, ch);
513 if (err) {
514 device_printf(d->dev, "pcm_chn_add(%s) failed, err=%d\n", ch->name, err);
515 snd_mtxunlock(d->lock);
516 pcm_chn_destroy(ch);
517 return err;
518 }
519
520 if (snd_maxautovchans > 0 && (d->flags & SD_F_AUTOVCHAN) &&

--- 15 unchanged lines hidden (view full) ---

536 struct snddev_info *d = device_get_softc(dev);
537 struct snddev_channel *sce;
538 struct pcm_channel *ch;
539 int error = 0;
540
541 sce = SLIST_FIRST(&d->channels);
542 ch = sce->channel;
543
530 if (err) {
531 device_printf(d->dev, "pcm_chn_add(%s) failed, err=%d\n", ch->name, err);
532 snd_mtxunlock(d->lock);
533 pcm_chn_destroy(ch);
534 return err;
535 }
536
537 if (snd_maxautovchans > 0 && (d->flags & SD_F_AUTOVCHAN) &&

--- 15 unchanged lines hidden (view full) ---

553 struct snddev_info *d = device_get_softc(dev);
554 struct snddev_channel *sce;
555 struct pcm_channel *ch;
556 int error = 0;
557
558 sce = SLIST_FIRST(&d->channels);
559 ch = sce->channel;
560
544 error = pcm_chn_remove(d, sce->channel, SLIST_EMPTY(&ch->children));
561 error = pcm_chn_remove(d, sce->channel);
545 if (error)
546 return (error);
547 return (pcm_chn_destroy(ch));
548}
549
550int
551pcm_setstatus(device_t dev, char *str)
552{

--- 127 unchanged lines hidden (view full) ---

680 snd_mtxunlock(d->lock);
681 return EBUSY;
682 }
683 if (sndstat_busy() != 0) {
684 device_printf(dev, "unregister: sndstat busy\n");
685 snd_mtxunlock(d->lock);
686 return EBUSY;
687 }
562 if (error)
563 return (error);
564 return (pcm_chn_destroy(ch));
565}
566
567int
568pcm_setstatus(device_t dev, char *str)
569{

--- 127 unchanged lines hidden (view full) ---

697 snd_mtxunlock(d->lock);
698 return EBUSY;
699 }
700 if (sndstat_busy() != 0) {
701 device_printf(dev, "unregister: sndstat busy\n");
702 snd_mtxunlock(d->lock);
703 return EBUSY;
704 }
705
706
688 SLIST_FOREACH(sce, &d->channels, link) {
689 ch = sce->channel;
690 if (ch->refcount > 0) {
691 device_printf(dev, "unregister: channel %s busy (pid %d)\n", ch->name, ch->pid);
692 snd_mtxunlock(d->lock);
693 return EBUSY;
694 }
695 }
707 SLIST_FOREACH(sce, &d->channels, link) {
708 ch = sce->channel;
709 if (ch->refcount > 0) {
710 device_printf(dev, "unregister: channel %s busy (pid %d)\n", ch->name, ch->pid);
711 snd_mtxunlock(d->lock);
712 return EBUSY;
713 }
714 }
715
716 SLIST_FOREACH(sce, &d->channels, link) {
717 destroy_dev(sce->dsp_devt);
718 destroy_dev(sce->dspW_devt);
719 destroy_dev(sce->audio_devt);
720 if (sce->dspr_devt)
721 destroy_dev(sce->dspr_devt);
722 }
723
696 if (mixer_uninit(dev)) {
697 device_printf(dev, "unregister: mixer busy\n");
698 snd_mtxunlock(d->lock);
699 return EBUSY;
700 }
701
702#ifdef SND_DYNSYSCTL
703 d->sysctl_tree_top = NULL;

--- 6 unchanged lines hidden (view full) ---

710 fkchan_kill(d->fakechan);
711
712 sndstat_unregister(dev);
713 snd_mtxunlock(d->lock);
714 snd_mtxfree(d->lock);
715 return 0;
716}
717
724 if (mixer_uninit(dev)) {
725 device_printf(dev, "unregister: mixer busy\n");
726 snd_mtxunlock(d->lock);
727 return EBUSY;
728 }
729
730#ifdef SND_DYNSYSCTL
731 d->sysctl_tree_top = NULL;

--- 6 unchanged lines hidden (view full) ---

738 fkchan_kill(d->fakechan);
739
740 sndstat_unregister(dev);
741 snd_mtxunlock(d->lock);
742 snd_mtxfree(d->lock);
743 return 0;
744}
745
718int
719pcm_regdevt(dev_t dev, unsigned unit, unsigned type, unsigned channel)
720{
721 struct snddev_info *d;
722 struct snddev_devt *dt;
723
724 d = devclass_get_softc(pcm_devclass, unit);
725 KASSERT((d != NULL), ("bad d"));
726 KASSERT((dev != NULL), ("bad dev"));
727
728 dt = malloc(sizeof(*dt), M_DEVBUF, M_ZERO | M_WAITOK);
729 if (dt == NULL)
730 return ENOMEM;
731 dt->dev = dev;
732 dt->type = type;
733 dt->channel = channel;
734
735 snd_mtxlock(d->lock);
736 SLIST_INSERT_HEAD(&d->devs, dt, link);
737 snd_mtxunlock(d->lock);
738
739 return 0;
740}
741
742dev_t
743pcm_getdevt(unsigned unit, unsigned type, unsigned channel)
744{
745 struct snddev_info *d;
746 struct snddev_devt *dt;
747
748 d = devclass_get_softc(pcm_devclass, unit);
749 KASSERT((d != NULL), ("bad d"));
750
751#if 0
752 snd_mtxlock(d->lock);
753#endif
754 SLIST_FOREACH(dt, &d->devs, link) {
755 if ((dt->type == type) && (dt->channel == channel))
756 return dt->dev;
757 }
758#if 0
759 snd_mtxunlock(d->lock);
760#endif
761
762 return NULL;
763}
764
765int
766pcm_unregdevt(unsigned unit, unsigned type, unsigned channel)
767{
768 struct snddev_info *d;
769 struct snddev_devt *dt;
770
771 d = devclass_get_softc(pcm_devclass, unit);
772 KASSERT((d != NULL), ("bad d"));
773
774#if 0
775 snd_mtxlock(d->lock);
776#endif
777 SLIST_FOREACH(dt, &d->devs, link) {
778 if ((dt->type == type) && (dt->channel == channel)) {
779 SLIST_REMOVE(&d->devs, dt, snddev_devt, link);
780 free(dt, M_DEVBUF);
781#if 0
782 snd_mtxunlock(d->lock);
783#endif
784 return 0;
785 }
786 }
787#if 0
788 snd_mtxunlock(d->lock);
789#endif
790
791 return ENOENT;
792}
793
794/************************************************************************/
795
796static int
797sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
798{
799 struct snddev_info *d;
800 struct snddev_channel *sce;
801 struct pcm_channel *c;

--- 205 unchanged lines hidden ---
746/************************************************************************/
747
748static int
749sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
750{
751 struct snddev_info *d;
752 struct snddev_channel *sce;
753 struct pcm_channel *c;

--- 205 unchanged lines hidden ---