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