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> |
31#include <sys/sysctl.h> 32 33#include "feeder_if.h" 34 |
35SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/sound.c 124740 2004-01-20 03:58:57Z matk $"); |
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 |
417pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch) |
418{ 419 struct snddev_channel *sce, *tmp, *after; |
420 int device = device_get_unit(d->dev); |
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 |
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++; |
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 } |
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); |
454 |
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); |
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 |
471 return 0; 472} 473 474int |
475pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch) |
476{ 477 struct snddev_channel *sce; |
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); |
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 |
529 err = pcm_chn_add(d, ch); |
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 |
561 error = pcm_chn_remove(d, sce->channel); |
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 |
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 |
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 |
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 --- |