channel.c revision 68413
1/* 2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 3 * Portions Copyright by Luigi Rizzo - 1997-99 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: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 * $FreeBSD: head/sys/dev/sound/pcm/channel.c 68413 2000-11-07 00:32:35Z cg $ 28 */ 29 30#include <dev/sound/pcm/sound.h> 31 32#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */ 33#define DMA_ALIGN_THRESHOLD 4 34#define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1)) 35 36#define ISA_DMA(b) (((b)->chan >= 0 && (b)->chan != 4 && (b)->chan < 8)) 37#define CANCHANGE(c) (!(c)->buffer.dl) 38#define ROUND(x) ((x) & DMA_ALIGN_MASK) 39 40/* 41#define DEB(x) x 42*/ 43 44static void buf_clear(snd_dbuf *b, u_int32_t fmt, int length); 45static void chn_dmaupdate(pcm_channel *c); 46static void chn_wrintr(pcm_channel *c); 47static void chn_rdintr(pcm_channel *c); 48static int chn_buildfeeder(pcm_channel *c); 49/* 50 * SOUND OUTPUT 51 52We use a circular buffer to store samples directed to the DAC. 53The buffer is split into two variable-size regions, each identified 54by an offset in the buffer (rp,fp) and a length (rl,fl): 55 56 0 rp,rl fp,fl bufsize 57 |__________>____________>________| 58 FREE d READY w FREE 59 60 READY: data written from the process and ready to be sent to the DAC; 61 FREE: free part of the buffer. 62 63Both regions can wrap around the end of the buffer. At initialization, 64READY is empty, FREE takes all the available space, and dma is 65idle. dl contains the length of the current DMA transfer, dl=0 66means that the dma is idle. 67 68The two boundaries (rp,fp) in the buffers are advanced by DMA [d] 69and write() [w] operations. The first portion of the READY region 70is used for DMA transfers. The transfer is started at rp and with 71chunks of length dl. During DMA operations, dsp_wr_dmaupdate() 72updates rp, rl and fl tracking the ISA DMA engine as the transfer 73makes progress. 74When a new block is written, fp advances and rl,fl are updated 75accordingly. 76 77The code works as follows: the user write routine dsp_write_body() 78fills up the READY region with new data (reclaiming space from the 79FREE region) and starts the write DMA engine if inactive. When a 80DMA transfer is complete, an interrupt causes dsp_wrintr() to be 81called which extends the FREE region and possibly starts the next 82transfer. 83 84In some cases, the code tries to track the current status of DMA 85operations by calling dsp_wr_dmaupdate() which changes rp, rl and fl. 86 87The system tries to make all DMA transfers use the same size, 88play_blocksize or rec_blocksize. The size is either selected by 89the user, or computed by the system to correspond to about .25s of 90audio. The blocksize must be within a range which is currently: 91 92 min(5ms, 40 bytes) ... 1/2 buffer size. 93 94When there aren't enough data (write) or space (read), a transfer 95is started with a reduced size. 96 97To reduce problems in case of overruns, the routine which fills up 98the buffer should initialize (e.g. by repeating the last value) a 99reasonably long area after the last block so that no noise is 100produced on overruns. 101 102 * 103 */ 104 105 106/* XXX this is broken: in the event a bounce buffer is used, data never 107 * gets copied in or out of the real buffer. fix requires mods to isa_dma.c 108 * and possibly fixes to other autodma mode clients 109 */ 110static void 111chn_isadmabounce(pcm_channel *c) 112{ 113 if (ISA_DMA(&c->buffer)) { 114 /* tell isa_dma to bounce data in/out */ 115 } else KASSERT(1, ("chn_isadmabounce called on invalid channel")); 116} 117 118static int 119chn_polltrigger(pcm_channel *c) 120{ 121 snd_dbuf *bs = &c->buffer2nd; 122 unsigned lim = (c->flags & CHN_F_HAS_SIZE)? bs->blksz : 0; 123 int trig = 0; 124 125 if (c->flags & CHN_F_MAPPED) 126 trig = ((bs->int_count > bs->prev_int_count) || bs->prev_int_count == 0); 127 else 128 trig = (((c->direction == PCMDIR_PLAY)? bs->fl : bs->rl) > lim); 129 return trig; 130} 131 132static int 133chn_pollreset(pcm_channel *c) 134{ 135 snd_dbuf *bs = &c->buffer2nd; 136 137 if (c->flags & CHN_F_MAPPED) 138 bs->prev_int_count = bs->int_count; 139 return 1; 140} 141 142/* 143 * chn_dmadone() updates pointers and wakes up any process waiting 144 * on a select(). Must be called at spltty(). 145 */ 146static void 147chn_dmadone(pcm_channel *c) 148{ 149 snd_dbuf *b = &c->buffer; 150 151 if (c->direction == PCMDIR_PLAY) 152 chn_checkunderflow(c); 153 else 154 chn_dmaupdate(c); 155 if (ISA_DMA(b)) 156 chn_isadmabounce(c); /* sync bounce buffer */ 157 b->int_count++; 158} 159 160/* 161 * chn_dmawakeup() wakes up any process sleeping. Separated from 162 * chn_dmadone() so that wakeup occurs only when feed from a 163 * secondary buffer to a DMA buffer takes place. Must be called 164 * at spltty(). 165 */ 166static void 167chn_dmawakeup(pcm_channel *c) 168{ 169 snd_dbuf *b = &c->buffer; 170 171 wakeup(b); 172} 173 174/* 175 * chn_dmaupdate() tracks the status of a dma transfer, 176 * updating pointers. It must be called at spltty(). 177 * 178 * NOTE: when we are using auto dma in the device, rl might become 179 * negative. 180 */ 181DEB (static int chn_updatecount=0); 182 183static void 184chn_dmaupdate(pcm_channel *c) 185{ 186 snd_dbuf *b = &c->buffer; 187 int delta, hwptr; 188 DEB (int b_rl=b->rl; int b_fl=b->fl; int b_rp=b->rp; int b_fp=b->fp); 189 190 hwptr = chn_getptr(c); 191 delta = (b->bufsize + hwptr - b->hp) % b->bufsize; 192 if (delta >= ((b->bufsize * 15) / 16)) { 193 if (!(c->flags & (CHN_F_CLOSING | CHN_F_ABORTING))) 194 device_printf(c->parent->dev, "hwptr went backwards %d -> %d\n", b->hp, hwptr); 195 } 196 if (c->direction == PCMDIR_PLAY) { 197 delta = (b->bufsize + hwptr - b->rp) % b->bufsize; 198 b->rp = hwptr; 199 b->rl -= delta; 200 b->fl += delta; 201 202 if (b->rl < 0) { 203 DEB(printf("OUCH!(%d) rl %d(%d) delta %d bufsize %d hwptr %d rp %d(%d)\n", chn_updatecount++, b->rl, b_rl, delta, b->bufsize, hwptr, b->rp, b_rp)); 204 } 205 } else { 206 delta = (b->bufsize + hwptr - b->fp) % b->bufsize; 207 b->fp = hwptr; 208 b->rl += delta; 209 b->fl -= delta; 210 if (b->fl < 0) { 211 DEB(printf("OUCH!(%d) fl %d(%d) delta %d bufsize %d hwptr %d fp %d(%d)\n", chn_updatecount++, b->fl, b_fl, delta, b->bufsize, hwptr, b->fp, b_fp)); 212 } 213 } 214 b->hp = hwptr; 215 b->total += delta; 216} 217 218/* 219 * Check channel for underflow occured. Reset DMA buffer in case of 220 * underflow, so that new data can go into the buffer. It must be 221 * called at spltty(). 222 */ 223void 224chn_checkunderflow(pcm_channel *c) 225{ 226 snd_dbuf *b = &c->buffer; 227 228 if (b->underflow) { 229 DEB(printf("Clear underflow condition\n")); 230 /* 231 * The DMA keeps running even after underflow occurs. 232 * Hence the value returned by chn_getptr() here soon 233 * gets a lag when we get back to chn_write(). Although 234 * there are no easy and precise methods to figure out 235 * the lag, a quarter of b->bufsize would be a fair 236 * choice, provided that a DMA interrupt generates upon 237 * each transfer of a half b->bufsize. 238 */ 239 b->rp = chn_getptr(c); 240 b->fp = (b->rp + b->bufsize / 4) % b->bufsize; 241 b->rl = b->bufsize / 4; 242 b->fl = b->bufsize - b->rl; 243 b->underflow = 0; 244 } else { 245 chn_dmaupdate(c); 246 } 247} 248 249/* 250 * Feeds new data to the write dma buffer. Can be called in the bottom half. 251 * Hence must be called at spltty. 252 */ 253int 254chn_wrfeed(pcm_channel *c) 255{ 256 snd_dbuf *b = &c->buffer; 257 snd_dbuf *bs = &c->buffer2nd; 258 int a, l, lacc; 259 260 /* ensure we always have a whole number of samples */ 261 a = (1 << c->align) - 1; 262 lacc = 0; 263 if (c->flags & CHN_F_MAPPED) { 264 bs->rl = min(b->blksz, b->fl); 265 bs->fl = 0; 266 a = 0; 267 } 268 DEB(if (c->flags & CHN_F_CLOSING) 269 printf("b: [rl: %d, rp %d, fl %d, fp %d]; bs: [rl: %d, rp %d, fl %d, fp %d]\n", 270 b->rl, b->rp, b->fl, b->fp, bs->rl, bs->rp, bs->fl, bs->fp)); 271 /* Don't allow write unaligned data */ 272 while (bs->rl > a && b->fl > a) { 273 /* ensure we always have a whole number of samples */ 274 l = min(min(bs->rl, bs->bufsize - bs->rp), min(b->fl, b->bufsize - b->fp)) & ~a; 275 if (l == 0) 276 return lacc; 277 /* Move the samples, update the markers and pointers. */ 278 bcopy(bs->buf + bs->rp, b->buf + b->fp, l); 279 bs->fl += l; 280 bs->rl -= l; 281 bs->rp = (bs->rp + l) % bs->bufsize; 282 b->rl += l; 283 b->fl -= l; 284 b->fp = (b->fp + l) % b->bufsize; 285 /* Clear the new space in the secondary buffer. */ 286 buf_clear(bs, bs->fmt, l); 287 /* Accumulate the total bytes of the moved samples. */ 288 lacc += l; 289 /* A feed to the DMA buffer is equivalent to an interrupt. */ 290 bs->total += l; 291 if (c->flags & CHN_F_MAPPED) { 292 if (bs->total - bs->prev_total >= bs->blksz) { 293 bs->prev_total = bs->total; 294 bs->int_count++; 295 c->blocks++; 296 } 297 } else 298 bs->int_count++; 299 if (bs->sel.si_pid && chn_polltrigger(c)) 300 selwakeup(&bs->sel); 301 } 302 303 return lacc; 304} 305 306/* Feeds new data to the secondary write buffer. */ 307static int 308chn_wrfeed2nd(pcm_channel *c, struct uio *buf) 309{ 310 snd_dbuf *bs = &c->buffer2nd; 311 int l, w, wacc, hl; 312 u_int8_t hackbuf[64]; 313 314 /* The DMA buffer may have some space. */ 315 while (chn_wrfeed(c) > 0); 316 317 /* ensure we always have a whole number of samples */ 318 wacc = 0; 319 hl = 0; 320 while (buf->uio_resid > 0 && bs->fl > 64) { 321 /* 322 * The size of the data to move here does not have to be 323 * aligned. We take care of it upon moving the data to a 324 * DMA buffer. 325 */ 326 l = min(bs->fl, bs->bufsize - bs->fp); 327 /* Move the samples, update the markers and pointers. */ 328 if (l < 64) { 329 w = c->feeder->feed(c->feeder, c, hackbuf, 64, buf); 330 l = min(w, bs->bufsize - bs->fp); 331 bcopy(hackbuf, bs->buf + bs->fp, l); 332 if (w > l) 333 bcopy(hackbuf + l, bs->buf, w - l); 334 } else 335 w = c->feeder->feed(c->feeder, c, bs->buf + bs->fp, l, buf); 336 if (w == 0) 337 panic("no feed"); 338 bs->rl += w; 339 bs->fl -= w; 340 bs->fp = (bs->fp + w) % bs->bufsize; 341 /* Accumulate the total bytes of the moved samples. */ 342 wacc += w; 343 344 /* If any pcm data gets moved, push it to the DMA buffer. */ 345 if (w > 0) 346 while (chn_wrfeed(c) > 0); 347 } 348 349 return wacc; 350} 351 352/* 353 * Write interrupt routine. Can be called from other places (e.g. 354 * to start a paused transfer), but with interrupts disabled. 355 */ 356static void 357chn_wrintr(pcm_channel *c) 358{ 359 snd_dbuf *b = &c->buffer; 360 361 if (b->underflow && !(c->flags & CHN_F_MAPPED)) { 362/* printf("underflow return\n"); 363*/ return; /* nothing new happened */ 364 } 365 if (b->dl) 366 chn_dmadone(c); 367 368 /* 369 * start another dma operation only if have ready data in the buffer, 370 * there is no pending abort, have a full-duplex device, or have a 371 * half duplex device and there is no pending op on the other side. 372 * 373 * Force transfers to be aligned to a boundary of 4, which is 374 * needed when doing stereo and 16-bit. 375 */ 376 377 /* Check underflow and update the pointers. */ 378 chn_checkunderflow(c); 379 380 /* 381 * Fill up the DMA buffer, followed by waking up the top half. 382 * If some of the pcm data in uio are still left, the top half 383 * goes to sleep by itself. 384 */ 385 if (c->flags & CHN_F_MAPPED) 386 chn_wrfeed(c); 387 else { 388 while (chn_wrfeed(c) > 0); 389 buf_clear(b, b->fmt, b->fl); 390 } 391 chn_dmawakeup(c); 392 if (c->flags & CHN_F_TRIGGERED) { 393 chn_dmaupdate(c); 394 /* 395 * check if we need to reprogram the DMA on the sound card. 396 * This happens if the size has changed from zero 397 */ 398 if (b->dl == 0) { 399 /* Start DMA operation */ 400 b->dl = b->blksz; /* record new transfer size */ 401 chn_trigger(c, PCMTRIG_START); 402 } 403 /* 404 * Emulate writing by DMA, i.e. transfer the pcm data from 405 * the emulated-DMA buffer to the device itself. 406 */ 407 chn_trigger(c, PCMTRIG_EMLDMAWR); 408 if (b->rl < b->dl) { 409 DEB(printf("near underflow (%d < %d), %d\n", b->rl, b->dl, b->fl)); 410 /* 411 * we are near to underflow condition, so to prevent 412 * audio 'clicks' clear next b->fl bytes 413 */ 414 buf_clear(b, b->fmt, b->fl); 415 if (b->rl < DMA_ALIGN_THRESHOLD) 416 b->underflow = 1; 417 } 418 } else { 419 /* cannot start a new dma transfer */ 420 DEB(printf("underflow, flags 0x%08x rp %d rl %d\n", c->flags, b->rp, b->rl)); 421 if (b->dl) { /* DMA was active */ 422 b->underflow = 1; /* set underflow flag */ 423 buf_clear(b, b->fmt, b->bufsize); 424 } 425 } 426} 427 428/* 429 * user write routine 430 * 431 * advance the boundary between READY and FREE, fill the space with 432 * uiomove(), and possibly start DMA. Do the above until the transfer 433 * is complete. 434 * 435 * To minimize latency in case a pending DMA transfer is about to end, 436 * we do the transfer in pieces of increasing sizes, extending the 437 * READY area at every checkpoint. In the (necessary) assumption that 438 * memory bandwidth is larger than the rate at which the dma consumes 439 * data, we reduce the latency to something proportional to the length 440 * of the first piece, while keeping the overhead low and being able 441 * to feed the DMA with large blocks. 442 */ 443 444int 445chn_write(pcm_channel *c, struct uio *buf) 446{ 447 int ret = 0, timeout, res, newsize, count; 448 long s; 449 snd_dbuf *b = &c->buffer; 450 snd_dbuf *bs = &c->buffer2nd; 451 452 if (c->flags & CHN_F_WRITING) { 453 /* This shouldn't happen and is actually silly 454 * - will never wake up, just timeout; why not sleep on b? 455 */ 456 tsleep(&s, PZERO, "pcmwrW", hz); 457 return EBUSY; 458 } 459 c->flags |= CHN_F_WRITING; 460 c->flags &= ~CHN_F_ABORTING; 461 s = spltty(); 462 463 /* 464 * XXX Certain applications attempt to write larger size 465 * of pcm data than c->blocksize2nd without blocking, 466 * resulting partial write. Expand the block size so that 467 * the write operation avoids blocking. 468 */ 469 if ((c->flags & CHN_F_NBIO) && buf->uio_resid > bs->blksz) { 470 DEB(printf("pcm warning: broken app, nbio and tried to write %d bytes with fragsz %d\n", 471 buf->uio_resid, bs->blksz)); 472 newsize = 16; 473 while (newsize < min(buf->uio_resid, CHN_2NDBUFMAXSIZE / 2)) 474 newsize <<= 1; 475 chn_setblocksize(c, bs->blkcnt, newsize); 476 DEB(printf("pcm warning: frags reset to %d x %d\n", bs->blkcnt, bs->blksz)); 477 } 478 479 /* 480 * Fill up the secondary and DMA buffer. 481 * chn_wrfeed*() takes care of the alignment. 482 */ 483 484 /* Check for underflow before writing into the buffers. */ 485 chn_checkunderflow(c); 486 while (chn_wrfeed2nd(c, buf) > 0); 487 if ((c->flags & CHN_F_NBIO) && (buf->uio_resid > 0)) 488 ret = EAGAIN; 489 490 /* Start playing if not yet. */ 491 if (!b->dl) 492 chn_start(c, 0); 493 494 if (ret == 0) { 495 count = hz; 496 /* Wait until all samples are played in blocking mode. */ 497 while ((buf->uio_resid > 0) && (count > 0)) { 498 /* Check for underflow before writing into the buffers. */ 499 chn_checkunderflow(c); 500 /* Fill up the buffers with new pcm data. */ 501 res = buf->uio_resid; 502 while (chn_wrfeed2nd(c, buf) > 0); 503 if (buf->uio_resid < res) 504 count = hz; 505 else 506 count--; 507 508 /* Have we finished to feed the secondary buffer? */ 509 if (buf->uio_resid == 0) 510 break; 511 512 /* Wait for new free space to write new pcm samples. */ 513 /* splx(s); */ 514 timeout = 1; /*(buf->uio_resid >= b->dl)? hz / 20 : 1; */ 515 ret = tsleep(b, PRIBIO | PCATCH, "pcmwr", timeout); 516 /* s = spltty(); */ 517 /* if (ret == EINTR) chn_abort(c); */ 518 if (ret == EINTR || ret == ERESTART) 519 break; 520 } 521 if (count == 0) { 522 c->flags |= CHN_F_DEAD; 523 device_printf(c->parent->dev, "play interrupt timeout, channel dead\n"); 524 } 525 } else 526 ret = 0; 527 c->flags &= ~CHN_F_WRITING; 528 splx(s); 529 return ret; 530} 531 532/* 533 * SOUND INPUT 534 * 535 536The input part is similar to the output one, with a circular buffer 537split in two regions, and boundaries advancing because of read() calls 538[r] or dma operation [d]. At initialization, as for the write 539routine, READY is empty, and FREE takes all the space. 540 541 0 rp,rl fp,fl bufsize 542 |__________>____________>________| 543 FREE r READY d FREE 544 545Operation is as follows: upon user read (dsp_read_body()) a DMA read 546is started if not already active (marked by b->dl > 0), 547then as soon as data are available in the READY region they are 548transferred to the user buffer, thus advancing the boundary between FREE 549and READY. Upon interrupts, caused by a completion of a DMA transfer, 550the READY region is extended and possibly a new transfer is started. 551 552When necessary, dsp_rd_dmaupdate() is called to advance fp (and update 553rl,fl accordingly). Upon user reads, rp is advanced and rl,fl are 554updated accordingly. 555 556The rules to choose the size of the new DMA area are similar to 557the other case, with a preferred constant transfer size equal to 558rec_blocksize, and fallback to smaller sizes if no space is available. 559 560 */ 561 562static int 563chn_rddump(pcm_channel *c, int cnt) 564{ 565 snd_dbuf *b = &c->buffer; 566 int maxover, ss; 567 568 ss = 1; 569 ss <<= (b->fmt & AFMT_STEREO)? 1 : 0; 570 ss <<= (b->fmt & AFMT_16BIT)? 1 : 0; 571 maxover = c->speed * ss; 572 573 b->overrun += cnt; 574 if (b->overrun > maxover) { 575 device_printf(c->parent->dev, "record overrun, dumping %d bytes\n", 576 b->overrun); 577 b->overrun = 0; 578 } 579 b->rl -= cnt; 580 b->fl += cnt; 581 b->rp = (b->rp + cnt) % b->bufsize; 582 return cnt; 583} 584 585/* 586 * Feed new data from the read buffer. Can be called in the bottom half. 587 * Hence must be called at spltty. 588 */ 589int 590chn_rdfeed(pcm_channel *c) 591{ 592 snd_dbuf *b = &c->buffer; 593 snd_dbuf *bs = &c->buffer2nd; 594 int l, lacc; 595 596 /* 597 printf("b: [rl: %d, rp %d, fl %d, fp %d]; bs: [rl: %d, rp %d, fl %d, fp %d]\n", 598 b->rl, b->rp, b->fl, b->fp, bs->rl, bs->rp, bs->fl, bs->fp); 599 */ 600 /* ensure we always have a whole number of samples */ 601 lacc = 0; 602 while (bs->fl >= DMA_ALIGN_THRESHOLD && b->rl >= DMA_ALIGN_THRESHOLD) { 603 l = min(min(bs->fl, bs->bufsize - bs->fp), min(b->rl, b->bufsize - b->rp)) & DMA_ALIGN_MASK; 604 /* Move the samples, update the markers and pointers. */ 605 bcopy(b->buf + b->rp, bs->buf + bs->fp, l); 606 bs->fl -= l; 607 bs->rl += l; 608 bs->fp = (bs->fp + l) % bs->bufsize; 609 b->rl -= l; 610 b->fl += l; 611 b->rp = (b->rp + l) % b->bufsize; 612 /* Accumulate the total bytes of the moved samples. */ 613 lacc += l; 614 /* A feed from the DMA buffer is equivalent to an interrupt. */ 615 bs->int_count++; 616 if (bs->sel.si_pid && chn_polltrigger(c)) 617 selwakeup(&bs->sel); 618 } 619 620 return lacc; 621} 622 623/* Feeds new data from the secondary read buffer. */ 624static int 625chn_rdfeed2nd(pcm_channel *c, struct uio *buf) 626{ 627 snd_dbuf *bs = &c->buffer2nd; 628 int l, w, wacc; 629 630 /* ensure we always have a whole number of samples */ 631 wacc = 0; 632 while ((buf->uio_resid > 0) && (bs->rl > 0)) { 633 /* The DMA buffer may have pcm data. */ 634 /* while (chn_rdfeed(c) > 0); */ 635 /* 636 * The size of the data to move here does not have to be 637 * aligned. We take care of it upon moving the data to a 638 * DMA buffer. 639 */ 640 l = min(bs->rl, bs->bufsize - bs->rp); 641 /* Move the samples, update the markers and pointers. */ 642 w = c->feeder->feed(c->feeder, c, bs->buf + bs->rp, l, buf); 643 if (w == 0) 644 panic("no feed"); 645 bs->fl += w; 646 bs->rl -= w; 647 bs->rp = (bs->rp + w) % bs->bufsize; 648 /* Clear the new space in the secondary buffer. */ 649 buf_clear(bs, bs->fmt, l); 650 /* Accumulate the total bytes of the moved samples. */ 651 bs->total += w; 652 wacc += w; 653 } 654 655 return wacc; 656} 657 658/* read interrupt routine. Must be called with interrupts blocked. */ 659static void 660chn_rdintr(pcm_channel *c) 661{ 662 snd_dbuf *b = &c->buffer; 663 664 if (b->dl) chn_dmadone(c); 665 666 DEB(printf("rdintr: start dl %d, rp:rl %d:%d, fp:fl %d:%d\n", 667 b->dl, b->rp, b->rl, b->fp, b->fl)); 668 669 /* Update the pointers. */ 670 chn_dmaupdate(c); 671 672 /* 673 * Suck up the DMA buffer, followed by waking up the top half. 674 * If some of the pcm data in the secondary buffer are still left, 675 * the top half goes to sleep by itself. 676 */ 677 while(chn_rdfeed(c) > 0); 678 chn_dmawakeup(c); 679 680 if (b->fl < b->dl) { 681 DEB(printf("near overflow (%d < %d), %d\n", b->fl, b->dl, b->rl)); 682 chn_rddump(c, b->blksz - b->fl); 683 } 684 685 if (c->flags & CHN_F_TRIGGERED) { 686 /* 687 * check if we need to reprogram the DMA on the sound card. 688 * This happens if the size has changed from zero 689 */ 690 if (b->dl == 0) { 691 /* Start DMA operation */ 692 b->dl = b->blksz; /* record new transfer size */ 693 chn_trigger(c, PCMTRIG_START); 694 } 695 /* 696 * Emulate writing by DMA, i.e. transfer the pcm data from 697 * the emulated-DMA buffer to the device itself. 698 */ 699 chn_trigger(c, PCMTRIG_EMLDMARD); 700 } else { 701 if (b->dl) { /* was active */ 702 b->dl = 0; 703 chn_trigger(c, PCMTRIG_STOP); 704 chn_dmaupdate(c); 705 } 706 } 707} 708 709/* 710 * body of user-read routine 711 * 712 * Start DMA if not active; wait for READY not empty. 713 * Transfer data from READY region using uiomove(), advance boundary 714 * between FREE and READY. Repeat until transfer is complete. 715 * 716 * To avoid excessive latency in freeing up space for the DMA 717 * engine, transfers are done in blocks of increasing size, so that 718 * the latency is proportional to the size of the smallest block, but 719 * we have a low overhead and are able to feed the dma engine with 720 * large blocks. 721 * 722 * NOTE: in the current version, read will not return more than 723 * blocksize bytes at once (unless more are already available), to 724 * avoid that requests using very large buffers block for too long. 725 */ 726 727int 728chn_read(pcm_channel *c, struct uio *buf) 729{ 730 int ret = 0, timeout, limit, res, count; 731 long s; 732 snd_dbuf *b = &c->buffer; 733 snd_dbuf *bs = &c->buffer2nd; 734 735 if (c->flags & CHN_F_READING) { 736 /* This shouldn't happen and is actually silly */ 737 tsleep(&s, PZERO, "pcmrdR", hz); 738 return (EBUSY); 739 } 740 741 s = spltty(); 742 743 /* Store the initial size in the uio. */ 744 res = buf->uio_resid; 745 746 c->flags |= CHN_F_READING; 747 c->flags &= ~CHN_F_ABORTING; 748 749 /* suck up the DMA and secondary buffers. */ 750 while (chn_rdfeed2nd(c, buf) > 0); 751 752 if (buf->uio_resid == 0) 753 goto skip; 754 755 limit = res - b->blksz; 756 if (limit < 0) 757 limit = 0; 758 759 /* Start capturing if not yet. */ 760 if ((!bs->rl || !b->rl) && !b->dl) 761 chn_start(c, 0); 762 763 if (!(c->flags & CHN_F_NBIO)) { 764 count = hz; 765 /* Wait until all samples are captured. */ 766 while ((buf->uio_resid > 0) && (count > 0)) { 767 /* Suck up the DMA and secondary buffers. */ 768 chn_dmaupdate(c); 769 res = buf->uio_resid; 770 while (chn_rdfeed(c) > 0); 771 while (chn_rdfeed2nd(c, buf) > 0); 772 if (buf->uio_resid < res) 773 count = hz; 774 else 775 count--; 776 777 /* Have we finished to feed the uio? */ 778 if (buf->uio_resid == 0) 779 break; 780 781 /* Wait for new pcm samples. */ 782 /* splx(s); */ 783 timeout = (buf->uio_resid - limit >= b->dl)? hz / 20 : 1; 784 ret = tsleep(b, PRIBIO | PCATCH, "pcmrd", 1); 785 /* s = spltty(); */ 786 /* if (ret == EINTR) chn_abort(c); */ 787 if (ret == EINTR || ret == ERESTART) 788 break; 789 } 790 if (count == 0) { 791 c->flags |= CHN_F_DEAD; 792 device_printf(c->parent->dev, "record interrupt timeout, channel dead\n"); 793 } 794 } else { 795 /* If no pcm data was read on nonblocking, return EAGAIN. */ 796 if (buf->uio_resid == res) 797 ret = EAGAIN; 798 } 799 800skip: 801 c->flags &= ~CHN_F_READING; 802 splx(s); 803 return ret; 804} 805 806void 807chn_intr(pcm_channel *c) 808{ 809 if (c->flags & CHN_F_INIT) 810 chn_reinit(c); 811 if (c->direction == PCMDIR_PLAY) 812 chn_wrintr(c); 813 else 814 chn_rdintr(c); 815} 816 817u_int32_t 818chn_start(pcm_channel *c, int force) 819{ 820 u_int32_t r, s; 821 snd_dbuf *b = &c->buffer; 822 823 r = 0; 824 s = spltty(); 825 if (b->dl == 0 && !(c->flags & CHN_F_NOTRIGGER)) { 826 if (c->direction == PCMDIR_PLAY) { 827 if (!(c->flags & CHN_F_MAPPED)) 828 while (chn_wrfeed(c) > 0); /* Fill up the DMA buffer. */ 829 if (force || (b->rl >= b->blksz)) 830 r = CHN_F_TRIGGERED; 831 } else { 832 if (!(c->flags & CHN_F_MAPPED)) 833 while (chn_rdfeed(c) > 0); /* Suck up the DMA buffer. */ 834 if (force || (b->fl >= b->blksz)) 835 r = CHN_F_TRIGGERED; 836 } 837 c->flags |= r; 838 chn_intr(c); 839 } 840 splx(s); 841 return r; 842} 843 844static void 845chn_dma_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) 846{ 847 snd_dbuf *b = (snd_dbuf *)arg; 848 849 if (bootverbose) { 850 printf("pcm: setmap %lx, %lx; ", (unsigned long)segs->ds_addr, 851 (unsigned long)segs->ds_len); 852 printf("%p -> %lx\n", b->buf, (unsigned long)vtophys(b->buf)); 853 } 854} 855 856/* 857 * Allocate memory for DMA buffer. If the device do not perform DMA transfer, 858 * the drvier can call malloc(9) by its own. 859 */ 860int 861chn_allocbuf(snd_dbuf *b, bus_dma_tag_t parent_dmat) 862{ 863 b->parent_dmat = parent_dmat; 864 if (bus_dmamem_alloc(b->parent_dmat, (void **)&b->buf, 865 BUS_DMA_NOWAIT, &b->dmamap)) return -1; 866 if (bus_dmamap_load(b->parent_dmat, b->dmamap, b->buf, 867 b->bufsize, chn_dma_setmap, b, 0)) return -1; 868 return 0; 869} 870 871void 872chn_freebuf(snd_dbuf *b) 873{ 874 bus_dmamem_free(b->parent_dmat, b->buf, b->dmamap); 875} 876 877static void 878buf_clear(snd_dbuf *b, u_int32_t fmt, int length) 879{ 880 int i; 881 u_int16_t data, *p; 882 883 if (length == 0) 884 return; 885 886 if (fmt & AFMT_SIGNED) 887 data = 0x00; 888 else 889 data = 0x80; 890 891 if (fmt & AFMT_16BIT) 892 data <<= 8; 893 else 894 data |= data << 8; 895 896 if (fmt & AFMT_BIGENDIAN) 897 data = ((data >> 8) & 0x00ff) | ((data << 8) & 0xff00); 898 899 i = b->fp; 900 p = (u_int16_t *)(b->buf + b->fp); 901 while (length > 1) { 902 *p++ = data; 903 length -= 2; 904 i += 2; 905 if (i >= b->bufsize) { 906 p = (u_int16_t *)b->buf; 907 i = 0; 908 } 909 } 910 if (length == 1) 911 *(b->buf + i) = data & 0xff; 912} 913 914void 915chn_resetbuf(pcm_channel *c) 916{ 917 snd_dbuf *b = &c->buffer; 918 snd_dbuf *bs = &c->buffer2nd; 919 920 c->blocks = 0; 921 b->rp = b->fp = 0; 922 b->dl = b->rl = 0; 923 b->fl = b->bufsize; 924 b->prev_total = b->total = 0; 925 b->prev_int_count = b->int_count = 0; 926 b->underflow = 0; 927 if (b->buf && b->bufsize > 0) 928 buf_clear(b, b->fmt, b->bufsize); 929 930 bs->rp = bs->fp = 0; 931 bs->dl = bs->rl = 0; 932 bs->fl = bs->bufsize; 933 bs->prev_total = bs->total = 0; 934 bs->prev_int_count = bs->int_count = 0; 935 bs->underflow = 0; 936 if (bs->buf && bs->bufsize > 0) 937 buf_clear(bs, bs->fmt, bs->bufsize); 938} 939 940void 941buf_isadma(snd_dbuf *b, int go) 942{ 943 KASSERT(b, ("buf_isadma called with b == NULL")); 944 KASSERT(ISA_DMA(b), ("buf_isadma called on non-ISA channel")); 945 946 switch (go) { 947 case PCMTRIG_START: 948 isa_dmastart(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->chan); 949 break; 950 951 case PCMTRIG_STOP: 952 case PCMTRIG_ABORT: 953 isa_dmastop(b->chan); 954 isa_dmadone(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->chan); 955 break; 956 } 957 958 DEB(printf("buf 0x%p ISA DMA %s, channel %d\n", 959 b, 960 (go == PCMTRIG_START)? "started" : "stopped", 961 b->chan)); 962} 963 964int 965buf_isadmaptr(snd_dbuf *b) 966{ 967 if (ISA_DMA(b)) { 968 int i = b->dl? isa_dmastatus(b->chan) : b->bufsize; 969 if (i < 0) 970 i = 0; 971 return b->bufsize - i; 972 } else KASSERT(1, ("buf_isadmaptr called on invalid channel")); 973 return -1; 974} 975 976/* 977 * chn_sync waits until the space in the given channel goes above 978 * a threshold. The threshold is checked against fl or rl respectively. 979 * Assume that the condition can become true, do not check here... 980 */ 981int 982chn_sync(pcm_channel *c, int threshold) 983{ 984 u_long s, rdy; 985 int ret; 986 snd_dbuf *b = &c->buffer; 987 snd_dbuf *bs = &c->buffer2nd; 988 989 for (;;) { 990 s = spltty(); 991 chn_checkunderflow(c); 992 while (chn_wrfeed(c) > 0); 993 rdy = (c->direction == PCMDIR_PLAY)? bs->fl : bs->rl; 994 if (rdy <= threshold) { 995 ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmsyn", 1); 996 splx(s); 997 if (ret == ERESTART || ret == EINTR) { 998 DEB(printf("chn_sync: tsleep returns %d\n", ret)); 999 return -1; 1000 } 1001 } else break; 1002 } 1003 splx(s); 1004 return 0; 1005} 1006 1007int 1008chn_poll(pcm_channel *c, int ev, struct proc *p) 1009{ 1010 snd_dbuf *b = &c->buffer; 1011 snd_dbuf *bs = &c->buffer2nd; 1012 u_long s; 1013 int ret; 1014 1015 s = spltty(); 1016 if (!(c->flags & CHN_F_MAPPED)) { 1017 if (c->direction == PCMDIR_PLAY) { 1018 /* Fill up the DMA buffer. */ 1019 chn_checkunderflow(c); 1020 while (chn_wrfeed(c) > 0); 1021 } else { 1022 /* Suck up the DMA buffer. */ 1023 chn_dmaupdate(c); 1024 while (chn_rdfeed(c) > 0); 1025 } 1026 if (!b->dl) 1027 chn_start(c, 1); 1028 } 1029 ret = 0; 1030 if (chn_polltrigger(c) && chn_pollreset(c)) 1031 ret = ev; 1032 else 1033 selrecord(p, &bs->sel); 1034 splx(s); 1035 return ret; 1036} 1037 1038/* 1039 * chn_abort is a non-blocking function which aborts a pending 1040 * DMA transfer and flushes the buffers. 1041 * It returns the number of bytes that have not been transferred. 1042 */ 1043int 1044chn_abort(pcm_channel *c) 1045{ 1046 int missing = 0, cnt = 0; 1047 snd_dbuf *b = &c->buffer; 1048 snd_dbuf *bs = &c->buffer2nd; 1049 1050 if (!b->dl) 1051 return 0; 1052 c->flags |= CHN_F_ABORTING; 1053 c->flags &= ~CHN_F_TRIGGERED; 1054 cnt = 10; 1055 while (!b->underflow && (cnt-- > 0)) 1056 tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmabr", hz / 50); 1057 chn_trigger(c, PCMTRIG_ABORT); 1058 b->dl = 0; 1059 chn_dmaupdate(c); 1060 missing = bs->rl + b->rl; 1061 return missing; 1062} 1063 1064/* 1065 * this routine tries to flush the dma transfer. It is called 1066 * on a close. We immediately abort any read DMA 1067 * operation, and then wait for the play buffer to drain. 1068 */ 1069 1070int 1071chn_flush(pcm_channel *c) 1072{ 1073 int ret, count, s, resid, resid_p; 1074 snd_dbuf *b = &c->buffer; 1075 snd_dbuf *bs = &c->buffer2nd; 1076 1077 DEB(printf("chn_flush c->flags 0x%08x\n", c->flags)); 1078 if (!b->dl) 1079 return 0; 1080 1081 c->flags |= CHN_F_CLOSING; 1082 if (c->direction == PCMDIR_REC) 1083 chn_abort(c); 1084 else { 1085 resid = b->rl + bs->rl; 1086 resid_p = resid; 1087 count = 10; 1088 while ((count > 0) && (resid > 0) && !b->underflow) { 1089 /* still pending output data. */ 1090 ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmflu", hz / 10); 1091 if (ret == EINTR || ret == ERESTART) { 1092 DEB(printf("chn_flush: tsleep returns %d\n", ret)); 1093 return ret; 1094 } 1095 s = spltty(); 1096 chn_dmaupdate(c); 1097 splx(s); 1098 DEB(printf("chn_flush: now rl = %d, fl = %d, resid = %d\n", b->rl, b->fl, resid)); 1099 resid = b->rl + bs->rl; 1100 if (resid >= resid_p) 1101 count--; 1102 resid_p = resid; 1103 } 1104 if (count == 0) 1105 DEB(printf("chn_flush: timeout flushing dbuf_out, cnt 0x%x flags 0x%x\n", b->rl, c->flags)); 1106 if (b->dl) 1107 chn_abort(c); 1108 } 1109 c->flags &= ~CHN_F_CLOSING; 1110 return 0; 1111} 1112 1113int 1114fmtvalid(u_int32_t fmt, u_int32_t *fmtlist) 1115{ 1116 int i; 1117 1118 for (i = 0; fmtlist[i]; i++) 1119 if (fmt == fmtlist[i]) 1120 return 1; 1121 return 0; 1122} 1123 1124int 1125chn_reset(pcm_channel *c, u_int32_t fmt) 1126{ 1127 int r = 0; 1128 1129 chn_abort(c); 1130 c->flags &= CHN_F_RESET; 1131 if (c->reset) 1132 c->reset(c->devinfo); 1133 r = chn_setblocksize(c, CHN_2NDBUFBLKNUM, CHN_2NDBUFBLKSIZE); 1134 if (r) 1135 return r; 1136 if (fmt) { 1137 c->speed = DSP_DEFAULT_SPEED; 1138 r = chn_setformat(c, fmt); 1139 if (r == 0) 1140 r = chn_setspeed(c, DSP_DEFAULT_SPEED); 1141 if (r == 0) 1142 r = chn_setvolume(c, 100, 100); 1143 } 1144 chn_resetbuf(c); 1145 if (c->resetdone) 1146 c->resetdone(c->devinfo); 1147 /* c->flags |= CHN_F_INIT; */ 1148 return 0; 1149} 1150 1151int 1152chn_reinit(pcm_channel *c) 1153{ 1154 if ((c->flags & CHN_F_INIT) && CANCHANGE(c)) { 1155 chn_setformat(c, c->format); 1156 chn_setspeed(c, c->speed); 1157 chn_setvolume(c, (c->volume >> 8) & 0xff, c->volume & 0xff); 1158 c->flags &= ~CHN_F_INIT; 1159 return 1; 1160 } 1161 return 0; 1162} 1163 1164int 1165chn_init(pcm_channel *c, void *devinfo, int dir) 1166{ 1167 snd_dbuf *bs = &c->buffer2nd; 1168 1169 /* Initialize the hardware and DMA buffer first. */ 1170 c->feeder = malloc(sizeof(*(c->feeder)), M_DEVBUF, M_NOWAIT); 1171 *(c->feeder) = *feeder_getroot(); 1172 c->feederdesc = malloc(sizeof(*(c->feeder)), M_DEVBUF, M_NOWAIT); 1173 c->feederdesc->type = FEEDER_ROOT; 1174 c->feederdesc->in = 0; 1175 c->feederdesc->out = 0; 1176 c->feederdesc->flags = 0; 1177 c->feederdesc->idx = 0; 1178 c->feeder->desc = c->feederdesc; 1179 c->feeder->source = NULL; 1180 1181 c->flags = 0; 1182 c->feederflags = 0; 1183 c->buffer.chan = -1; 1184 c->devinfo = c->init(devinfo, &c->buffer, c, dir); 1185 if (c->devinfo == NULL || c->buffer.bufsize == 0) 1186 return 1; 1187 chn_setdir(c, dir); 1188 1189 /* And the secondary buffer. */ 1190 bs->buf = NULL; 1191 bs->bufsize = 0; 1192 return 0; 1193} 1194 1195int 1196chn_kill(pcm_channel *c) 1197{ 1198 if (c->flags & CHN_F_TRIGGERED) 1199 chn_trigger(c, PCMTRIG_ABORT); 1200 while (chn_removefeeder(c) == 0); 1201 free(c->feeder->desc, M_DEVBUF); 1202 free(c->feeder, M_DEVBUF); 1203 if (c->free) 1204 c->free(c->devinfo); 1205 else 1206 chn_freebuf(&c->buffer); 1207 c->flags |= CHN_F_DEAD; 1208 return 0; 1209} 1210 1211int 1212chn_setdir(pcm_channel *c, int dir) 1213{ 1214 int r; 1215 1216 c->direction = dir; 1217 r = c->setdir? c->setdir(c->devinfo, c->direction) : 0; 1218 if (!r && ISA_DMA(&c->buffer)) 1219 c->buffer.dir = (dir == PCMDIR_PLAY)? ISADMA_WRITE : ISADMA_READ; 1220 return r; 1221} 1222 1223int 1224chn_setvolume(pcm_channel *c, int left, int right) 1225{ 1226 /* could add a feeder for volume changing if channel returns -1 */ 1227 if (CANCHANGE(c)) { 1228 c->volume = (left << 8) | right; 1229 return 0; 1230 } 1231 c->volume = (left << 8) | right; 1232 c->flags |= CHN_F_INIT; 1233 return 0; 1234} 1235 1236int 1237chn_setspeed(pcm_channel *c, int speed) 1238{ 1239 pcm_feeder *f; 1240 int r, hwspd, delta; 1241 1242 DEB(printf("want speed %d, ", speed)); 1243 if (speed <= 0) 1244 return EINVAL; 1245 if (CANCHANGE(c)) { 1246 c->speed = speed; 1247 hwspd = speed; 1248 RANGE(hwspd, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed); 1249 DEB(printf("try speed %d, ", hwspd)); 1250 hwspd = c->setspeed(c->devinfo, hwspd); 1251 DEB(printf("got speed %d, ", hwspd)); 1252 delta = hwspd - speed; 1253 if (delta < 0) 1254 delta = -delta; 1255 c->feederflags &= ~(1 << FEEDER_RATE); 1256 if (delta > 500) 1257 c->feederflags |= 1 << FEEDER_RATE; 1258 else 1259 speed = hwspd; 1260 r = chn_buildfeeder(c); 1261 DEB(printf("r = %d\n", r)); 1262 if (r) 1263 return r; 1264 if (!(c->feederflags & (1 << FEEDER_RATE))) 1265 return 0; 1266 f = chn_findfeeder(c, FEEDER_RATE); 1267 DEB(printf("feedrate = %p\n", f)); 1268 if (f == NULL) 1269 return EINVAL; 1270 r = feeder_set(f, FEEDRATE_SRC, speed); 1271 DEB(printf("feeder_set(FEEDRATE_SRC, %d) = %d\n", speed, r)); 1272 if (r) 1273 return r; 1274 r = feeder_set(f, FEEDRATE_DST, hwspd); 1275 DEB(printf("feeder_set(FEEDRATE_DST, %d) = %d\n", hwspd, r)); 1276 if (r) 1277 return r; 1278 return 0; 1279 } 1280 c->speed = speed; 1281 c->flags |= CHN_F_INIT; 1282 return 0; 1283} 1284 1285int 1286chn_setformat(pcm_channel *c, u_int32_t fmt) 1287{ 1288 snd_dbuf *b = &c->buffer; 1289 snd_dbuf *bs = &c->buffer2nd; 1290 int r; 1291 1292 u_int32_t hwfmt; 1293 if (CANCHANGE(c)) { 1294 DEB(printf("want format %d\n", fmt)); 1295 c->format = fmt; 1296 c->feederdesc->out = c->format; 1297 hwfmt = c->format; 1298 c->feederflags &= ~(1 << FEEDER_FMT); 1299 if (!fmtvalid(hwfmt, chn_getcaps(c)->fmtlist)) 1300 c->feederflags |= 1 << FEEDER_FMT; 1301 r = chn_buildfeeder(c); 1302 if (r) 1303 return r; 1304 hwfmt = c->feeder->desc->out; 1305 b->fmt = hwfmt; 1306 bs->fmt = hwfmt; 1307 chn_resetbuf(c); 1308 c->setformat(c->devinfo, hwfmt); 1309 return chn_setspeed(c, c->speed); 1310 } 1311 c->format = fmt; 1312 c->flags |= CHN_F_INIT; 1313 return 0; 1314} 1315 1316int 1317chn_setblocksize(pcm_channel *c, int blkcnt, int blksz) 1318{ 1319 snd_dbuf *b = &c->buffer; 1320 snd_dbuf *bs = &c->buffer2nd; 1321 int s, ss, bufsz; 1322 1323 if (bs->blkcnt == blkcnt && bs->blksz == blksz) 1324 return 0; 1325 if (c->flags & CHN_F_MAPPED) { 1326 DEB(printf("chn_setblocksize: can't work on mapped channel")); 1327 return EINVAL; 1328 } 1329 c->flags &= ~CHN_F_HAS_SIZE; 1330 1331 ss = 1; 1332 ss <<= (bs->fmt & AFMT_STEREO)? 1 : 0; 1333 ss <<= (bs->fmt & AFMT_16BIT)? 1 : 0; 1334 1335 if (blksz >= 2) 1336 c->flags |= CHN_F_HAS_SIZE; 1337 /* let us specify blksz without setting CHN_F_HAS_SIZE */ 1338 if (blksz < 0) 1339 blksz = -blksz; 1340 /* default to blksz = ~0.25s */ 1341 if (blksz < 16) 1342 blksz = (ss * c->speed) >> 2; 1343 if (blksz > CHN_2NDBUFMAXSIZE / 2) 1344 blksz = CHN_2NDBUFMAXSIZE / 2; 1345 if (blkcnt < 2) 1346 blkcnt = 2; 1347 1348 if (blkcnt * blksz > CHN_2NDBUFMAXSIZE) 1349 blkcnt = CHN_2NDBUFMAXSIZE / blksz; 1350 bufsz = blkcnt * blksz; 1351 1352 s = spltty(); 1353 if (bs->buf != NULL) 1354 free(bs->buf, M_DEVBUF); 1355 bs->buf = malloc(bufsz, M_DEVBUF, M_WAITOK); 1356 if (bs->buf == NULL) { 1357 splx(s); 1358 DEB(printf("chn_setblocksize: out of memory.")); 1359 return ENOSPC; 1360 } 1361 bs->bufsize = bufsz; 1362 bs->rl = bs->rp = bs->fp = 0; 1363 bs->fl = bs->bufsize; 1364 buf_clear(bs, bs->fmt, bs->bufsize); 1365 bs->blkcnt = blkcnt; 1366 bs->blksz = blksz; 1367 RANGE(blksz, 16, b->bufsize / 2); 1368 b->blksz = c->setblocksize(c->devinfo, blksz); 1369 splx(s); 1370 1371 return 0; 1372} 1373 1374int 1375chn_trigger(pcm_channel *c, int go) 1376{ 1377 return c->trigger(c->devinfo, go); 1378} 1379 1380int 1381chn_getptr(pcm_channel *c) 1382{ 1383 int hwptr; 1384 int a = (1 << c->align) - 1; 1385 snd_dbuf *b = &c->buffer; 1386 1387 hwptr = b->dl? c->getptr(c->devinfo) : 0; 1388 /* don't allow unaligned values in the hwa ptr */ 1389 hwptr &= ~a ; /* Apply channel align mask */ 1390 hwptr &= DMA_ALIGN_MASK; /* Apply DMA align mask */ 1391 return hwptr; 1392} 1393 1394pcmchan_caps * 1395chn_getcaps(pcm_channel *c) 1396{ 1397 return c->getcaps(c->devinfo); 1398} 1399 1400u_int32_t 1401chn_getformats(pcm_channel *c) 1402{ 1403 u_int32_t *fmtlist, fmts; 1404 int i; 1405 1406 fmtlist = chn_getcaps(c)->fmtlist; 1407 fmts = 0; 1408 for (i = 0; fmtlist[i]; i++) 1409 fmts |= fmtlist[i]; 1410 1411 return fmts; 1412} 1413 1414static int 1415chn_buildfeeder(pcm_channel *c) 1416{ 1417 pcm_feeder *f; 1418 struct pcm_feederdesc desc; 1419 u_int32_t tmp[2], src, dst, type, flags; 1420 1421 while (chn_removefeeder(c) == 0); 1422 c->align = 0; 1423 flags = c->feederflags; 1424 src = c->feeder->desc->out; 1425 if ((c->flags & CHN_F_MAPPED) && (flags != 0)) 1426 return EINVAL; 1427 DEB(printf("not mapped, flags %x, ", flags)); 1428 for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) { 1429 if (flags & (1 << type)) { 1430 desc.type = type; 1431 desc.in = 0; 1432 desc.out = 0; 1433 desc.flags = 0; 1434 DEB(printf("find feeder type %d, ", type)); 1435 f = feeder_get(&desc); 1436 DEB(printf("got %p\n", f)); 1437 if (f == NULL) 1438 return EINVAL; 1439 dst = f->desc->in; 1440 if (src != dst) { 1441 DEB(printf("build fmtchain from %x to %x: ", src, dst)); 1442 tmp[0] = dst; 1443 tmp[1] = 0; 1444 if (chn_fmtchain(c, tmp) == 0) 1445 return EINVAL; 1446 DEB(printf("ok\n")); 1447 } 1448 if (chn_addfeeder(c, f)) 1449 return EINVAL; 1450 src = f->desc->out; 1451 DEB(printf("added feeder %p, output %x\n", f, src)); 1452 dst = 0; 1453 flags &= ~(1 << type); 1454 } 1455 } 1456 if (!fmtvalid(src, chn_getcaps(c)->fmtlist)) { 1457 if (chn_fmtchain(c, chn_getcaps(c)->fmtlist) == 0) 1458 return EINVAL; 1459 DEB(printf("built fmtchain from %x to %x\n", src, c->feeder->desc->out)); 1460 flags &= ~(1 << FEEDER_FMT); 1461 } 1462 return 0; 1463} 1464