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$ 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 39 static void chn_stintr(pcm_channel *c); 40 static void chn_clearbuf(pcm_channel *c, int length); 41 /* 42 * SOUND OUTPUT 43 44 We use a circular buffer to store samples directed to the DAC. 45 The buffer is split into two variable-size regions, each identified 46 by an offset in the buffer (rp,fp) and a length (rl,fl): 47 48 0 rp,rl fp,fl bufsize 49 |__________>____________>________| 50 FREE d READY w FREE 51 52 READY: data written from the process and ready to be sent to the DAC; 53 FREE: free part of the buffer. 54 55 Both regions can wrap around the end of the buffer. At initialization, 56 READY is empty, FREE takes all the available space, and dma is 57 idle. dl contains the length of the current DMA transfer, dl=0 58 means that the dma is idle. 59 60 The two boundaries (rp,fp) in the buffers are advanced by DMA [d] 61 and write() [w] operations. The first portion of the READY region 62 is used for DMA transfers. The transfer is started at rp and with 63 chunks of length dl. During DMA operations, dsp_wr_dmaupdate() 64 updates rp, rl and fl tracking the ISA DMA engine as the transfer 65 makes progress. 66 When a new block is written, fp advances and rl,fl are updated 67 accordingly. 68 69 The code works as follows: the user write routine dsp_write_body() 70 fills up the READY region with new data (reclaiming space from the 71 FREE region) and starts the write DMA engine if inactive. When a 72 DMA transfer is complete, an interrupt causes dsp_wrintr() to be 73 called which extends the FREE region and possibly starts the next 74 transfer. 75 76 In some cases, the code tries to track the current status of DMA 77 operations by calling dsp_wr_dmaupdate() which changes rp, rl and fl. 78 79 The sistem tries to make all DMA transfers use the same size, 80 play_blocksize or rec_blocksize. The size is either selected by 81 the user, or computed by the system to correspond to about .25s of 82 audio. The blocksize must be within a range which is currently: 83 84 min(5ms, 40 bytes) ... 1/2 buffer size. 85 86 When there aren't enough data (write) or space (read), a transfer 87 is started with a reduced size. 88 89 To reduce problems in case of overruns, the routine which fills up 90 the buffer should initialize (e.g. by repeating the last value) a 91 reasonably long area after the last block so that no noise is 92 produced on overruns. 93 94 * 95 */ 96 97 98 /* XXX this is broken: in the event a bounce buffer is used, data never 99 * gets copied in or out of the real buffer. fix requires mods to isa_dma.c 100 * and possibly fixes to other autodma mode clients 101 */ 102 static void 103 chn_isadmabounce(pcm_channel *c) 104 { 105 if (ISA_DMA(&c->buffer)) { 106 /* tell isa_dma to bounce data in/out */ 107 } else KASSERT(1, ("chn_isadmabounce called on invalid channel")); 108 } 109 110 static int 111 chn_polltrigger(pcm_channel *c) 112 { 113 snd_dbuf *b = &c->buffer; 114 unsigned lim = (c->flags & CHN_F_HAS_SIZE)? c->blocksize : 1; 115 int trig = 0; 116 117 if (c->flags & CHN_F_MAPPED) 118 trig = ((b->int_count > b->prev_int_count) || b->first_poll); 119 else trig = (((c->direction == PCMDIR_PLAY)? b->fl : b->rl) >= lim); 120 return trig; 121 } 122 123 static int 124 chn_pollreset(pcm_channel *c) 125 { 126 snd_dbuf *b = &c->buffer; 127 128 if (c->flags & CHN_F_MAPPED) b->prev_int_count = b->int_count; 129 b->first_poll = 0; 130 return 1; 131 } 132 133 /* 134 * chn_dmadone() updates pointers and wakes up any process waiting 135 * on a select(). Must be called at spltty(). 136 */ 137 static void 138 chn_dmadone(pcm_channel *c) 139 { 140 snd_dbuf *b = &c->buffer; 141 142 chn_dmaupdate(c); 143 if (ISA_DMA(b)) chn_isadmabounce(c); /* sync bounce buffer */ 144 b->int_count++; 145 if (b->sel.si_pid && chn_polltrigger(c)) selwakeup(&b->sel); 146 } 147 148 /* 149 * chn_dmawakeup() wakes up any process sleeping. Separated from 150 * chn_dma_done() so that wakeup occurs only when feed from a 151 * secondary buffer to a DMA buffer takes place. Must be called 152 * at spltty(). 153 */ 154 static void 155 chn_dmawakeup(pcm_channel *c) 156 { 157 snd_dbuf *b = &c->buffer; 158 159 wakeup(b); 160 } 161 162 /* 163 * chn_dmaupdate() tracks the status of a dma transfer, 164 * updating pointers. It must be called at spltty(). 165 * 166 * NOTE: when we are using auto dma in the device, rl might become 167 * negative. 168 */ 169 DEB (static int chn_updatecount=0); 170 171 void 172 chn_dmaupdate(pcm_channel *c) 173 { 174 snd_dbuf *b = &c->buffer; 175 int delta, hwptr; 176 DEB (int b_rl=b->rl; int b_fl=b->fl; int b_rp=b->rp; int b_fp=b->fp); 177 178 hwptr = chn_getptr(c); 179 if (c->direction == PCMDIR_PLAY) { 180 delta = (b->bufsize + hwptr - b->rp) % b->bufsize; 181 b->rp = hwptr; 182 b->rl -= delta; 183 b->fl += delta; 184 DEB(if (b->rl<0) 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)); 185 } else { 186 delta = (b->bufsize + hwptr - b->fp) % b->bufsize; 187 b->fp = hwptr; 188 b->rl += delta; 189 b->fl -= delta; 190 DEB(if (b->fl<0) 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)); 191 } 192 b->total += delta; 193 } 194 195 /* 196 * Check channel for underflow occured. Reset DMA buffer in case of 197 * underflow, so that new data can go into the buffer. It must be 198 * called at spltty(). 199 */ 200 static void 201 chn_checkunderflow(pcm_channel *c) 202 { 203 snd_dbuf *b = &c->buffer; 204 205 if (b->underflow) { 206 DEB(printf("Clear underflow condition\n")); 207 /* 208 * The DMA keeps running even after underflow occurs. 209 * Hence the value returned by chn_getptr() here soon 210 * gets a lag when we get back to chn_write(). Although 211 * there are no easy and precise methods to figure out 212 * the lag, a quarter of b->bufsize would be a fair 213 * choice, provided that a DMA interrupt generates upon 214 * each transfer of a half b->bufsize. 215 */ 216 b->rp = chn_getptr(c); 217 b->fp = (b->rp + b->bufsize / 4) % b->bufsize; 218 b->rl = b->bufsize / 4; 219 b->fl = b->bufsize - b->rl; 220 b->underflow=0; 221 } else { 222 chn_dmaupdate(c); 223 } 224 } 225 226 /* 227 * Feeds new data to the write dma buffer. Can be called in the bottom half. 228 * Hence must be called at spltty. 229 */ 230 static int 231 chn_wrfeed(pcm_channel *c) 232 { 233 snd_dbuf *b = &c->buffer; 234 snd_dbuf *bs = &c->buffer2nd; 235 int a, l, lacc; 236 237 /* ensure we always have a whole number of samples */ 238 a = (1 << c->align) - 1; 239 lacc = 0; 240 /* Don't allow write unaligned data */ 241 while (bs->rl > a && b->fl > a) { 242 /* ensure we always have a whole number of samples */ 243 l = min(min(bs->rl, bs->bufsize - bs->rp), min(b->fl, b->bufsize - b->fp)) & ~a; 244 if (l == 0) 245 return lacc; 246 /* Move the samples, update the markers and pointers. */ 247 bcopy(bs->buf + bs->rp, b->buf + b->fp, l); 248 bs->fl += l; 249 bs->rl -= l; 250 bs->rp = (bs->rp + l) % bs->bufsize; 251 b->rl += l; 252 b->fl -= l; 253 b->fp = (b->fp + l) % b->bufsize; 254 /* Accumulate the total bytes of the moved samples. */ 255 lacc += l; 256 } 257 258 return lacc; 259 } 260 261 /* Feeds new data to the secondary write buffer. */ 262 static int 263 chn_wrfeed2nd(pcm_channel *c, struct uio *buf) 264 { 265 snd_dbuf *bs = &c->buffer2nd; 266 int l, w, wacc; 267 268 /* ensure we always have a whole number of samples */ 269 wacc = 0; 270 while (buf->uio_resid > 0 && bs->fl > 0) { 271 /* 272 * The size of the data to move here does not have to be 273 * aligned. We take care of it upon moving the data to a 274 * DMA buffer. 275 */ 276 l = min(bs->fl, bs->bufsize - bs->fp); 277 /* Move the samples, update the markers and pointers. */ 278 w = c->feeder->feed(c->feeder, c, bs->buf + bs->fp, l, buf); 279 if (w == 0) panic("no feed"); 280 bs->rl += w; 281 bs->fl -= w; 282 bs->fp = (bs->fp + w) % bs->bufsize; 283 /* Accumulate the total bytes of the moved samples. */ 284 wacc += w; 285 } 286 287 return wacc; 288 } 289 290 /* 291 * Write interrupt routine. Can be called from other places (e.g. 292 * to start a paused transfer), but with interrupts disabled. 293 */ 294 static void 295 chn_wrintr(pcm_channel *c) 296 { 297 snd_dbuf *b = &c->buffer; 298 int start; 299 300 if (b->underflow && !(c->flags & CHN_F_MAPPED)) return; /* nothing new happened */ 301 if (b->dl) chn_dmadone(c); 302 303 /* 304 * start another dma operation only if have ready data in the buffer, 305 * there is no pending abort, have a full-duplex device, or have a 306 * half duplex device and there is no pending op on the other side. 307 * 308 * Force transfers to be aligned to a boundary of 4, which is 309 * needed when doing stereo and 16-bit. 310 */ 311 if (c->flags & CHN_F_MAPPED) start = c->flags & CHN_F_TRIGGERED; 312 else { 313 /* 314 * Fill up the DMA buffer. This may result in making new 315 * free space in the secondary buffer, thus we can wake up 316 * the top half if feed occurs. 317 */ 318 if (chn_wrfeed(c) > 0) { 319 chn_dmawakeup(c); 320 while (chn_wrfeed(c) > 0); 321 } 322 start = (b->rl >= DMA_ALIGN_THRESHOLD && !(c->flags & CHN_F_ABORTING)); 323 } 324 if (start) { 325 int l; 326 chn_dmaupdate(c); 327 if (c->flags & CHN_F_MAPPED) l = c->blocksize; 328 else l = min(b->rl, c->blocksize) & DMA_ALIGN_MASK; 329 /* 330 * check if we need to reprogram the DMA on the sound card. 331 * This happens if the size has changed from zero 332 */ 333 if (b->dl == 0) { 334 /* Start DMA operation */ 335 b->dl = c->blocksize; /* record new transfer size */ 336 chn_trigger(c, PCMTRIG_START); 337 } 338 if (b->dl != l) 339 /* 340 * we are near to underflow condition, so to prevent 341 * audio 'clicks' clear next b->fl bytes 342 */ 343 chn_clearbuf(c, b->fl); 344 } else { 345 /* cannot start a new dma transfer */ 346 DEB(printf("cannot start wr-dma flags 0x%08x rp %d rl %d\n", 347 c->flags, b->rp, b->rl)); 348 if (b->dl) { /* DMA was active */ 349 chn_trigger(c, PCMTRIG_STOP); 350 b->dl = 0; 351 b->underflow = 1; /* set underflow flag */ 352 chn_clearbuf(c, b->bufsize); /* and clear all DMA buffer */ 353 } 354 } 355 } 356 357 /* 358 * user write routine 359 * 360 * advance the boundary between READY and FREE, fill the space with 361 * uiomove(), and possibly start DMA. Do the above until the transfer 362 * is complete. 363 * 364 * To minimize latency in case a pending DMA transfer is about to end, 365 * we do the transfer in pieces of increasing sizes, extending the 366 * READY area at every checkpoint. In the (necessary) assumption that 367 * memory bandwidth is larger than the rate at which the dma consumes 368 * data, we reduce the latency to something proportional to the length 369 * of the first piece, while keeping the overhead low and being able 370 * to feed the DMA with large blocks. 371 */ 372 373 int 374 chn_write(pcm_channel *c, struct uio *buf) 375 { 376 int ret = 0, timeout; 377 long s; 378 snd_dbuf *b = &c->buffer; 379 380 if (c->flags & CHN_F_WRITING) { 381 /* This shouldn't happen and is actually silly 382 * - will never wake up, just timeout; why not sleep on b? 383 */ 384 tsleep(&s, PZERO, "pcmwrW", hz); 385 return EBUSY; 386 } 387 c->flags |= CHN_F_WRITING; 388 /* 389 * Fill up the secondary and DMA buffer. 390 * chn_wrfeed*() takes care of the alignment. 391 */ 392 s = spltty(); 393 /* Check for underflow before writing into the buffers. */ 394 chn_checkunderflow(c); 395 while (chn_wrfeed2nd(c, buf) > 0 || chn_wrfeed(c) > 0); 396 /* Start playing if not yet. */ 397 if (b->rl && !b->dl) chn_wrintr(c); 398 if (!(c->flags & CHN_F_NBIO)) { 399 /* Wait until all samples are played in blocking mode. */ 400 while (buf->uio_resid > 0) { 401 splx(s); 402 /* Wait for new free space to write new pcm samples. */ 403 timeout = (buf->uio_resid >= b->dl)? hz / 20 : 1; 404 ret = tsleep(b, PRIBIO | PCATCH, "pcmwr", timeout); 405 s = spltty(); 406 if (ret == EINTR) chn_abort(c); 407 if (ret == EINTR || ret == ERESTART) break; 408 /* Check for underflow before writing into the buffers. */ 409 chn_checkunderflow(c); 410 /* Fill up the buffers with new pcm data. */ 411 while (chn_wrfeed2nd(c, buf) > 0 || chn_wrfeed(c) > 0); 412 /* Start playing if necessary. */ 413 if (b->rl && !b->dl) chn_wrintr(c); 414 } 415 } 416 c->flags &= ~CHN_F_WRITING; 417 splx(s); 418 return (ret > 0)? ret : 0; 419 } 420 421 /* 422 * SOUND INPUT 423 * 424 425 The input part is similar to the output one, with a circular buffer 426 split in two regions, and boundaries advancing because of read() calls 427 [r] or dma operation [d]. At initialization, as for the write 428 routine, READY is empty, and FREE takes all the space. 429 430 0 rp,rl fp,fl bufsize 431 |__________>____________>________| 432 FREE r READY d FREE 433 434 Operation is as follows: upon user read (dsp_read_body()) a DMA read 435 is started if not already active (marked by b->dl > 0), 436 then as soon as data are available in the READY region they are 437 transferred to the user buffer, thus advancing the boundary between FREE 438 and READY. Upon interrupts, caused by a completion of a DMA transfer, 439 the READY region is extended and possibly a new transfer is started. 440 441 When necessary, dsp_rd_dmaupdate() is called to advance fp (and update 442 rl,fl accordingly). Upon user reads, rp is advanced and rl,fl are 443 updated accordingly. 444 445 The rules to choose the size of the new DMA area are similar to 446 the other case, with a preferred constant transfer size equal to 447 rec_blocksize, and fallback to smaller sizes if no space is available. 448 449 */ 450 451 /* 452 * Feed new data from the read buffer. Can be called in the bottom half. 453 * Hence must be called at spltty. 454 */ 455 static int 456 chn_rdfeed(pcm_channel *c) 457 { 458 snd_dbuf *b = &c->buffer; 459 snd_dbuf *bs = &c->buffer2nd; 460 int l, lacc; 461 462 /* ensure we always have a whole number of samples */ 463 lacc = 0; 464 while (bs->fl >= DMA_ALIGN_THRESHOLD && b->rl >= DMA_ALIGN_THRESHOLD) { 465 l = min(min(bs->fl, bs->bufsize - bs->fp), min(b->rl, b->bufsize - b->rp)) & DMA_ALIGN_MASK; 466 /* Move the samples, update the markers and pointers. */ 467 bcopy(b->buf + b->rp, bs->buf + bs->fp, l); 468 bs->fl -= l; 469 bs->rl += l; 470 bs->fp = (bs->fp + l) % bs->bufsize; 471 b->rl -= l; 472 b->fl += l; 473 b->rp = (b->rp + l) % b->bufsize; 474 /* Accumulate the total bytes of the moved samples. */ 475 lacc += l; 476 } 477 478 return lacc; 479 } 480 481 /* Feeds new data from the secondary read buffer. */ 482 static int 483 chn_rdfeed2nd(pcm_channel *c, struct uio *buf) 484 { 485 snd_dbuf *bs = &c->buffer2nd; 486 int l, w, wacc; 487 488 /* ensure we always have a whole number of samples */ 489 wacc = 0; 490 while (buf->uio_resid > 0 && bs->rl > 0) { 491 /* 492 * The size of the data to move here does not have to be 493 * aligned. We take care of it upon moving the data to a 494 * DMA buffer. 495 */ 496 l = min(bs->rl, bs->bufsize - bs->rp); 497 /* Move the samples, update the markers and pointers. */ 498 w = c->feeder->feed(c->feeder, c, bs->buf + bs->rp, l, buf); 499 if (w == 0) panic("no feed"); 500 bs->fl += w; 501 bs->rl -= w; 502 bs->rp = (bs->rp + w) % bs->bufsize; 503 /* Accumulate the total bytes of the moved samples. */ 504 wacc += w; 505 } 506 507 return wacc; 508 } 509 510 /* read interrupt routine. Must be called with interrupts blocked. */ 511 static void 512 chn_rdintr(pcm_channel *c) 513 { 514 snd_dbuf *b = &c->buffer; 515 int start; 516 517 if (b->dl) chn_dmadone(c); 518 519 DEB(printf("rdintr: start dl %d, rp:rl %d:%d, fp:fl %d:%d\n", 520 b->dl, b->rp, b->rl, b->fp, b->fl)); 521 /* Restart if have enough free space to absorb overruns */ 522 if (c->flags & CHN_F_MAPPED) start = c->flags & CHN_F_TRIGGERED; 523 else { 524 /* 525 * Suck up the DMA buffer. This may result in making new 526 * captured data in the secondary buffer, thus we can wake 527 * up the top half if feed occurs. 528 */ 529 if (chn_rdfeed(c) > 0) { 530 chn_dmawakeup(c); 531 while (chn_rdfeed(c) > 0); 532 } 533 start = (b->fl > 0x200 && !(c->flags & CHN_F_ABORTING)); 534 } 535 if (start) { 536 int l = min(b->fl - 0x100, c->blocksize); 537 if (c->flags & CHN_F_MAPPED) l = c->blocksize; 538 l &= DMA_ALIGN_MASK ; /* realign sizes */ 539 540 DEB(printf("rdintr: dl %d -> %d\n", b->dl, l);) 541 if (l != b->dl) { 542 /* size has changed. Stop and restart */ 543 if (b->dl) { 544 chn_trigger(c, PCMTRIG_STOP); 545 chn_dmaupdate(c); 546 l = min(b->fl - 0x100, c->blocksize); 547 l &= DMA_ALIGN_MASK ; /* realign sizes */ 548 } 549 b->dl = l; 550 chn_trigger(c, PCMTRIG_START); 551 } 552 } else { 553 if (b->dl) { /* was active */ 554 b->dl = 0; 555 chn_dmaupdate(c); 556 chn_trigger(c, PCMTRIG_STOP); 557 } 558 } 559 } 560 561 /* 562 * body of user-read routine 563 * 564 * Start DMA if not active; wait for READY not empty. 565 * Transfer data from READY region using uiomove(), advance boundary 566 * between FREE and READY. Repeat until transfer is complete. 567 * 568 * To avoid excessive latency in freeing up space for the DMA 569 * engine, transfers are done in blocks of increasing size, so that 570 * the latency is proportional to the size of the smallest block, but 571 * we have a low overhead and are able to feed the dma engine with 572 * large blocks. 573 * 574 * NOTE: in the current version, read will not return more than 575 * blocksize bytes at once (unless more are already available), to 576 * avoid that requests using very large buffers block for too long. 577 */ 578 579 int 580 chn_read(pcm_channel *c, struct uio *buf) 581 { 582 int ret = 0, timeout, limit; 583 long s; 584 snd_dbuf *b = &c->buffer; 585 586 if (c->flags & CHN_F_READING) { 587 /* This shouldn't happen and is actually silly */ 588 tsleep(&s, PZERO, "pcmrdR", hz); 589 return (EBUSY); 590 } 591 592 s = spltty(); 593 c->flags |= CHN_F_READING; 594 limit = buf->uio_resid - c->blocksize; 595 if (limit < 0) limit = 0; 596 /* Start capturing if not yet. */ 597 if (!b->rl & !b->dl) chn_rdintr(c); 598 /* Suck up the DMA and secondary buffers. */ 599 while (chn_rdfeed(c) > 0 || chn_rdfeed2nd(c, buf) > 0); 600 if (!(c->flags & CHN_F_NBIO)) { 601 /* Wait until all samples are captured. */ 602 while (buf->uio_resid > 0) { 603 splx(s); 604 /* Wait for new pcm samples. */ 605 timeout = (buf->uio_resid - limit >= b->dl)? hz / 20 : 1; 606 ret = tsleep(b, PRIBIO | PCATCH, "pcmrd", timeout); 607 s = spltty(); 608 if (ret == EINTR) chn_abort(c); 609 if (ret == EINTR || ret == ERESTART) break; 610 /* Start capturing if necessary. */ 611 if (!b->rl & !b->dl) chn_rdintr(c); 612 /* Suck up the DMA and secondary buffers. */ 613 while (chn_rdfeed(c) > 0 || chn_rdfeed2nd(c, buf) > 0); 614 } 615 } 616 c->flags &= ~CHN_F_READING; 617 splx(s); 618 return ret; 619 } 620 621 void 622 chn_intr(pcm_channel *c) 623 { 624 /* if (!c->buffer.dl) chn_reinit(c); 625 */ if (c->direction == PCMDIR_PLAY) chn_wrintr(c); else chn_rdintr(c); 626 } 627 628 static void 629 chn_stintr(pcm_channel *c) 630 { 631 u_long s; 632 s = spltty(); 633 chn_intr(c); 634 splx(s); 635 } 636 637 static void 638 chn_dma_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) 639 { 640 snd_dbuf *b = (snd_dbuf *)arg; 641 642 if (bootverbose) { 643 printf("pcm: setmap %lx, %lx; ", (unsigned long)segs->ds_addr, 644 (unsigned long)segs->ds_len); 645 printf("%p -> %lx\n", b->buf, (unsigned long)vtophys(b->buf)); 646 } 647 } 648 649 int 650 chn_allocbuf(snd_dbuf *b, bus_dma_tag_t parent_dmat) 651 { 652 if (bus_dmamem_alloc(parent_dmat, (void **)&b->buf, 653 BUS_DMA_NOWAIT, &b->dmamap)) return -1; 654 if (bus_dmamap_load(parent_dmat, b->dmamap, b->buf, 655 b->bufsize, chn_dma_setmap, b, 0)) return -1; 656 return 0; 657 } 658 659 static void 660 chn_clearbuf(pcm_channel *c, int length) 661 { 662 int i; 663 u_int16_t data, *p; 664 665 snd_dbuf *b = &c->buffer; 666 /* rely on length & DMA_ALIGN_MASK == 0 */ 667 length&=DMA_ALIGN_MASK; 668 if (c->hwfmt & AFMT_SIGNED) data = 0x00; else data = 0x80; 669 if (c->hwfmt & AFMT_16BIT) data <<= 8; else data |= data << 8; 670 if (c->hwfmt & AFMT_BIGENDIAN) 671 data = ((data >> 8) & 0x00ff) | ((data << 8) & 0xff00); 672 for (i = b->fp, p=(u_int16_t*)(b->buf+b->fp) ; i < b->bufsize && length; i += 2, length-=2) 673 *p++ = data; 674 for (i = 0, p=(u_int16_t*)b->buf; i < b->bufsize && length; i += 2, length-=2) 675 *p++ = data; 676 677 return; 678 } 679 680 void 681 chn_resetbuf(pcm_channel *c) 682 { 683 snd_dbuf *b = &c->buffer; 684 snd_dbuf *bs = &c->buffer2nd; 685 686 c->smegcnt = 0; 687 c->buffer.sample_size = 1; 688 c->buffer.sample_size <<= (c->hwfmt & AFMT_STEREO)? 1 : 0; 689 c->buffer.sample_size <<= (c->hwfmt & AFMT_16BIT)? 1 : 0; 690 b->rp = b->fp = 0; 691 b->dl = b->rl = 0; 692 b->fl = b->bufsize; 693 chn_clearbuf(c, b->bufsize); 694 b->prev_total = b->total = 0; 695 b->prev_int_count = b->int_count = 0; 696 b->first_poll = 1; 697 b->underflow=0; 698 bs->rp = bs->fp = 0; 699 bs->dl = bs->rl = 0; 700 bs->fl = bs->bufsize; 701 } 702 703 void 704 buf_isadma(snd_dbuf *b, int go) 705 { 706 if (ISA_DMA(b)) { 707 if (go == PCMTRIG_START) { 708 DEB(printf("buf 0x%p ISA DMA started\n", b)); 709 isa_dmastart(b->dir | B_RAW, b->buf, 710 b->bufsize, b->chan); 711 } else { 712 DEB(printf("buf 0x%p ISA DMA stopped\n", b)); 713 isa_dmastop(b->chan); 714 isa_dmadone(b->dir | B_RAW, b->buf, b->bufsize, 715 b->chan); 716 } 717 } else KASSERT(1, ("buf_isadma called on invalid channel")); 718 } 719 720 int 721 buf_isadmaptr(snd_dbuf *b) 722 { 723 if (ISA_DMA(b)) { 724 int i = b->dl? isa_dmastatus(b->chan) : b->bufsize; 725 if (i < 0) i = 0; 726 return b->bufsize - i; 727 } else KASSERT(1, ("buf_isadmaptr called on invalid channel")); 728 return -1; 729 } 730 731 /* 732 * snd_sync waits until the space in the given channel goes above 733 * a threshold. The threshold is checked against fl or rl respectively. 734 * Assume that the condition can become true, do not check here... 735 */ 736 int 737 chn_sync(pcm_channel *c, int threshold) 738 { 739 u_long s, rdy; 740 int ret; 741 snd_dbuf *b = &c->buffer; 742 743 for (;;) { 744 s = spltty(); 745 chn_dmaupdate(c); 746 rdy = (c->direction == PCMDIR_PLAY)? b->fl : b->rl; 747 if (rdy <= threshold) { 748 ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmsyn", 1); 749 splx(s); 750 if (ret == ERESTART || ret == EINTR) { 751 DEB(printf("chn_sync: tsleep returns %d\n", ret)); 752 return -1; 753 } 754 } else break; 755 } 756 splx(s); 757 return 0; 758 } 759 760 int 761 chn_poll(pcm_channel *c, int ev, struct proc *p) 762 { 763 snd_dbuf *b = &c->buffer; 764 u_long s = spltty(); 765 if (b->dl) chn_dmaupdate(c); 766 splx(s); 767 if (chn_polltrigger(c) && chn_pollreset(c)) return ev; 768 else { 769 selrecord(p, &b->sel); 770 return 0; 771 } 772 } 773 774 /* 775 * chn_abort is a non-blocking function which aborts a pending 776 * DMA transfer and flushes the buffers. 777 * It returns the number of bytes that have not been transferred. 778 */ 779 int 780 chn_abort(pcm_channel *c) 781 { 782 int missing = 0, cnt = 0; 783 snd_dbuf *b = &c->buffer; 784 snd_dbuf *bs = &c->buffer2nd; 785 786 if (!b->dl) return 0; 787 c->flags |= CHN_F_ABORTING; 788 while (!b->underflow && (b->dl > 0) && (cnt < 20)) { 789 tsleep((caddr_t)b, PRIBIO, "pcmabr", hz / 20); 790 cnt++; 791 } 792 chn_trigger(c, PCMTRIG_ABORT); 793 b->dl = 0; 794 missing = b->rl + bs->rl; 795 return missing; 796 } 797 798 /* 799 * this routine tries to flush the dma transfer. It is called 800 * on a close. We immediately abort any read DMA 801 * operation, and then wait for the play buffer to drain. 802 */ 803 804 int 805 chn_flush(pcm_channel *c) 806 { 807 int ret, count = 10; 808 snd_dbuf *b = &c->buffer; 809 810 DEB(printf("snd_flush c->flags 0x%08x\n", c->flags)); 811 c->flags |= CHN_F_CLOSING; 812 if (c->direction != PCMDIR_PLAY) chn_abort(c); 813 else if (b->dl) while (!b->underflow) { 814 /* still pending output data. */ 815 ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmflu", hz); 816 DEB(chn_dmaupdate(c)); 817 DEB(printf("snd_sync: now rl : fl %d : %d\n", b->rl, b->fl)); 818 if (ret == EINTR || ret == ERESTART) { 819 DEB(printf("chn_flush: tsleep returns %d\n", ret)); 820 return -1; 821 } 822 if (ret && --count == 0) { 823 DEB(printf("chn_flush: timeout flushing dbuf_out, cnt 0x%x flags 0x%x\n",\ 824 b->rl, c->flags)); 825 break; 826 } 827 } 828 c->flags &= ~CHN_F_CLOSING; 829 if (c->direction == PCMDIR_PLAY) chn_abort(c); 830 return 0; 831 } 832 833 int 834 chn_reset(pcm_channel *c) 835 { 836 chn_abort(c); 837 c->flags &= CHN_F_RESET; 838 chn_resetbuf(c); 839 c->flags |= CHN_F_INIT; 840 return 0; 841 } 842 843 int 844 chn_reinit(pcm_channel *c) 845 { 846 if ((c->flags & CHN_F_INIT) && CANCHANGE(c)) { 847 chn_setformat(c, c->format); 848 chn_setspeed(c, c->speed); 849 chn_setblocksize(c, (c->flags & CHN_F_HAS_SIZE) ? c->blocksize : 0); 850 chn_setvolume(c, (c->volume >> 8) & 0xff, c->volume & 0xff); 851 c->flags &= ~CHN_F_INIT; 852 return 1; 853 } 854 if (CANCHANGE(c) && !(c->flags & CHN_F_HAS_SIZE) ) 855 chn_setblocksize(c, 0); /* Apply new block size */ 856 return 0; 857 } 858 859 int 860 chn_init(pcm_channel *c, void *devinfo, int dir) 861 { 862 snd_dbuf *bs = &c->buffer2nd; 863 864 c->flags = 0; 865 c->feeder = &feeder_root; 866 c->buffer.chan = -1; 867 c->devinfo = c->init(devinfo, &c->buffer, c, dir); 868 chn_setdir(c, dir); 869 bs->bufsize = CHN_2NDBUFBLKSIZE * CHN_2NDBUFBLKNUM; 870 bs->buf = malloc(bs->bufsize, M_DEVBUF, M_NOWAIT); 871 bzero(bs->buf, bs->bufsize); 872 bs->rl = bs->rp = bs->fp = 0; 873 bs->fl = bs->bufsize; 874 return 0; 875 } 876 877 int 878 chn_setdir(pcm_channel *c, int dir) 879 { 880 c->direction = dir; 881 if (ISA_DMA(&c->buffer)) 882 c->buffer.dir = (dir == PCMDIR_PLAY)? B_WRITE : B_READ; 883 return c->setdir(c->devinfo, c->direction); 884 } 885 886 int 887 chn_setvolume(pcm_channel *c, int left, int right) 888 { 889 /* could add a feeder for volume changing if channel returns -1 */ 890 if (CANCHANGE(c)) { 891 return -1; 892 } 893 c->volume = (left << 8) | right; 894 c->flags |= CHN_F_INIT; 895 return 0; 896 } 897 898 int 899 chn_setspeed(pcm_channel *c, int speed) 900 { 901 /* could add a feeder for rate conversion */ 902 if (CANCHANGE(c)) { 903 c->speed = c->setspeed(c->devinfo, speed); 904 return c->speed; 905 } 906 c->speed = speed; 907 c->flags |= CHN_F_INIT; 908 return 0; 909 } 910 911 int 912 chn_setformat(pcm_channel *c, u_int32_t fmt) 913 { 914 if (CANCHANGE(c)) { 915 c->hwfmt = c->format = fmt; 916 c->hwfmt = chn_feedchain(c); 917 chn_resetbuf(c); 918 c->setformat(c->devinfo, c->hwfmt); 919 return fmt; 920 } 921 c->format = fmt; 922 c->flags |= CHN_F_INIT; 923 return 0; 924 } 925 926 int 927 chn_setblocksize(pcm_channel *c, int blksz) 928 { 929 if (CANCHANGE(c)) { 930 c->flags &= ~CHN_F_HAS_SIZE; 931 if (blksz >= 2) c->flags |= CHN_F_HAS_SIZE; 932 if (blksz < 0) blksz = -blksz; 933 if (blksz < 2) blksz = c->buffer.sample_size * (c->speed >> 2); 934 RANGE(blksz, 1024, c->buffer.bufsize / 4); 935 blksz &= DMA_ALIGN_MASK; 936 c->blocksize = c->setblocksize(c->devinfo, blksz) & DMA_ALIGN_MASK; 937 return c->blocksize; 938 } 939 c->blocksize = blksz; 940 c->flags |= CHN_F_INIT; 941 return 0; 942 } 943 944 int 945 chn_trigger(pcm_channel *c, int go) 946 { 947 return c->trigger(c->devinfo, go); 948 } 949 950 int 951 chn_getptr(pcm_channel *c) 952 { 953 int hwptr; 954 int a = (1 << c->align) - 1; 955 956 hwptr=c->getptr(c->devinfo); 957 /* don't allow unaligned values in the hwa ptr */ 958 hwptr &= ~a ; /* Apply channel align mask */ 959 hwptr &= DMA_ALIGN_MASK; /* Apply DMA align mask */ 960 return hwptr; 961 } 962 963 pcmchan_caps * 964 chn_getcaps(pcm_channel *c) 965 { 966 return c->getcaps(c->devinfo); 967 } 968