sound.c (82492) | sound.c (83089) |
---|---|
1/* 2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 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: --- 17 unchanged lines hidden (view full) --- 26 */ 27 28#include <dev/sound/pcm/sound.h> 29#include <dev/sound/pcm/vchan.h> 30#include <sys/sysctl.h> 31 32#include "feeder_if.h" 33 | 1/* 2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 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: --- 17 unchanged lines hidden (view full) --- 26 */ 27 28#include <dev/sound/pcm/sound.h> 29#include <dev/sound/pcm/vchan.h> 30#include <sys/sysctl.h> 31 32#include "feeder_if.h" 33 |
34SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/sound.c 82492 2001-08-29 09:17:43Z cg $"); | 34SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/sound.c 83089 2001-09-05 16:28:41Z cg $"); |
35 36struct snddev_channel { 37 SLIST_ENTRY(snddev_channel) link; 38 struct pcm_channel *channel; 39}; 40 41struct snddev_info { 42 SLIST_HEAD(, snddev_channel) channels; 43 struct pcm_channel *fakechan; | 35 36struct snddev_channel { 37 SLIST_ENTRY(snddev_channel) link; 38 struct pcm_channel *channel; 39}; 40 41struct snddev_info { 42 SLIST_HEAD(, snddev_channel) channels; 43 struct pcm_channel *fakechan; |
44 unsigned devcount, chancount, vchancount; | 44 unsigned devcount, reccount, chancount, vchancount; |
45 unsigned flags; 46 int inprog; 47 void *devinfo; 48 device_t dev; 49 char status[SND_STATUSLEN]; 50 struct sysctl_ctx_list sysctl_tree; 51 struct sysctl_oid *sysctl_tree_top; 52 void *lock; --- 116 unchanged lines hidden (view full) --- 169struct pcm_channel * 170pcm_getfakechan(struct snddev_info *d) 171{ 172 return d->fakechan; 173} 174 175/* return a locked channel */ 176struct pcm_channel * | 45 unsigned flags; 46 int inprog; 47 void *devinfo; 48 device_t dev; 49 char status[SND_STATUSLEN]; 50 struct sysctl_ctx_list sysctl_tree; 51 struct sysctl_oid *sysctl_tree_top; 52 void *lock; --- 116 unchanged lines hidden (view full) --- 169struct pcm_channel * 170pcm_getfakechan(struct snddev_info *d) 171{ 172 return d->fakechan; 173} 174 175/* return a locked channel */ 176struct pcm_channel * |
177pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid) | 177pcm_chnalloc(struct snddev_info *d, int direction, pid_t pid, int chnum) |
178{ 179 struct pcm_channel *c; 180 struct snddev_channel *sce; 181 int err; 182 183 snd_mtxassert(d->lock); 184 185 /* scan for a free channel */ 186 SLIST_FOREACH(sce, &d->channels, link) { 187 c = sce->channel; 188 CHN_LOCK(c); 189 if ((c->direction == direction) && !(c->flags & CHN_F_BUSY)) { | 178{ 179 struct pcm_channel *c; 180 struct snddev_channel *sce; 181 int err; 182 183 snd_mtxassert(d->lock); 184 185 /* scan for a free channel */ 186 SLIST_FOREACH(sce, &d->channels, link) { 187 c = sce->channel; 188 CHN_LOCK(c); 189 if ((c->direction == direction) && !(c->flags & CHN_F_BUSY)) { |
190 c->flags |= CHN_F_BUSY; 191 c->pid = pid; 192 return c; | 190 if (chnum == -1 || c->num == chnum) { 191 c->flags |= CHN_F_BUSY; 192 c->pid = pid; 193 return c; 194 } |
193 } 194 CHN_UNLOCK(c); 195 } 196 197 /* no channel available */ 198 if (direction == PCMDIR_PLAY) { 199 if ((d->vchancount > 0) && (d->vchancount < snd_maxautovchans)) { 200 /* try to create a vchan */ 201 SLIST_FOREACH(sce, &d->channels, link) { 202 c = sce->channel; 203 if (!SLIST_EMPTY(&c->children)) { 204 err = vchan_create(c); 205 if (!err) | 195 } 196 CHN_UNLOCK(c); 197 } 198 199 /* no channel available */ 200 if (direction == PCMDIR_PLAY) { 201 if ((d->vchancount > 0) && (d->vchancount < snd_maxautovchans)) { 202 /* try to create a vchan */ 203 SLIST_FOREACH(sce, &d->channels, link) { 204 c = sce->channel; 205 if (!SLIST_EMPTY(&c->children)) { 206 err = vchan_create(c); 207 if (!err) |
206 return pcm_chnalloc(d, direction, pid); | 208 return pcm_chnalloc(d, direction, pid, -1); |
207 else 208 device_printf(d->dev, "vchan_create(%s) == %d\n", c->name, err); 209 } 210 } 211 } 212 } 213 214 return NULL; --- 202 unchanged lines hidden (view full) --- 417 } else { 418 after = NULL; 419 SLIST_FOREACH(tmp, &d->channels, link) { 420 after = tmp; 421 } 422 SLIST_INSERT_AFTER(after, sce, link); 423 } 424 | 209 else 210 device_printf(d->dev, "vchan_create(%s) == %d\n", c->name, err); 211 } 212 } 213 } 214 } 215 216 return NULL; --- 202 unchanged lines hidden (view full) --- 419 } else { 420 after = NULL; 421 SLIST_FOREACH(tmp, &d->channels, link) { 422 after = tmp; 423 } 424 SLIST_INSERT_AFTER(after, sce, link); 425 } 426 |
425 if (mkdev) | 427 if (ch->direction == PCMDIR_REC) 428 ch->num = d->reccount++; 429/* 430 else 431 ch->num = d->playcount++; 432*/ 433 434 if (mkdev) { |
426 dsp_register(unit, d->devcount++); | 435 dsp_register(unit, d->devcount++); |
436 if (ch->direction == PCMDIR_REC) 437 dsp_registerrec(unit, ch->num); 438 } |
|
427 d->chancount++; 428 if (ch->flags & CHN_F_VIRTUAL) 429 d->vchancount++; 430 431 snd_mtxunlock(d->lock); 432 433 return 0; 434} --- 13 unchanged lines hidden (view full) --- 448 return EINVAL; 449gotit: 450 if (ch->flags & CHN_F_VIRTUAL) 451 d->vchancount--; 452 d->chancount--; 453 SLIST_REMOVE(&d->channels, sce, snddev_channel, link); 454 free(sce, M_DEVBUF); 455 | 439 d->chancount++; 440 if (ch->flags & CHN_F_VIRTUAL) 441 d->vchancount++; 442 443 snd_mtxunlock(d->lock); 444 445 return 0; 446} --- 13 unchanged lines hidden (view full) --- 460 return EINVAL; 461gotit: 462 if (ch->flags & CHN_F_VIRTUAL) 463 d->vchancount--; 464 d->chancount--; 465 SLIST_REMOVE(&d->channels, sce, snddev_channel, link); 466 free(sce, M_DEVBUF); 467 |
456 if (rmdev) | 468 if (rmdev) { |
457 dsp_unregister(unit, --d->devcount); | 469 dsp_unregister(unit, --d->devcount); |
470 if (ch->direction == PCMDIR_REC) 471 dsp_unregisterrec(unit, --d->reccount); 472 } |
|
458 snd_mtxunlock(d->lock); 459 460 return 0; 461} 462 463int 464pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo) 465{ --- 81 unchanged lines hidden (view full) --- 547 548 d->lock = snd_mtxcreate(device_get_nameunit(dev)); 549 snd_mtxlock(d->lock); 550 551 d->flags = 0; 552 d->dev = dev; 553 d->devinfo = devinfo; 554 d->devcount = 0; | 473 snd_mtxunlock(d->lock); 474 475 return 0; 476} 477 478int 479pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo) 480{ --- 81 unchanged lines hidden (view full) --- 562 563 d->lock = snd_mtxcreate(device_get_nameunit(dev)); 564 snd_mtxlock(d->lock); 565 566 d->flags = 0; 567 d->dev = dev; 568 d->devinfo = devinfo; 569 d->devcount = 0; |
570 d->reccount = 0; |
|
555 d->chancount = 0; 556 d->vchancount = 0; 557 d->inprog = 0; 558 559 if (((numplay == 0) || (numrec == 0)) && (numplay != numrec)) 560 d->flags |= SD_F_SIMPLEX; 561 562 d->fakechan = fkchan_setup(dev); --- 244 unchanged lines hidden --- | 571 d->chancount = 0; 572 d->vchancount = 0; 573 d->inprog = 0; 574 575 if (((numplay == 0) || (numrec == 0)) && (numplay != numrec)) 576 d->flags |= SD_F_SIMPLEX; 577 578 d->fakechan = fkchan_setup(dev); --- 244 unchanged lines hidden --- |