The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sound/pcm/buffer.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <dev/sound/pcm/sound.h>
   28 
   29 #include "feeder_if.h"
   30 
   31 SND_DECLARE_FILE("$FreeBSD: releng/5.0/sys/dev/sound/pcm/buffer.c 107237 2002-11-25 17:17:43Z cg $");
   32 
   33 #define MIN(x, y) (((x) < (y))? (x) : (y))
   34 
   35 #define SNDBUF_NAMELEN  48
   36 struct snd_dbuf {
   37         device_t dev;
   38         u_int8_t *buf, *tmpbuf;
   39         unsigned int bufsize, maxsize;
   40         volatile int dl; /* transfer size */
   41         volatile int rp; /* pointers to the ready area */
   42         volatile int rl; /* length of ready area */
   43         volatile int hp;
   44         volatile u_int32_t total, prev_total;
   45         int isadmachan, dir;       /* dma channel */
   46         u_int32_t fmt, spd, bps;
   47         unsigned int blksz, blkcnt;
   48         int xrun;
   49         u_int32_t flags;
   50         bus_dmamap_t dmamap;
   51         bus_dma_tag_t dmatag;
   52         struct selinfo sel;
   53         char name[SNDBUF_NAMELEN];
   54 };
   55 
   56 struct snd_dbuf *
   57 sndbuf_create(device_t dev, char *drv, char *desc)
   58 {
   59         struct snd_dbuf *b;
   60 
   61         b = malloc(sizeof(*b), M_DEVBUF, M_WAITOK | M_ZERO);
   62         snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", drv, desc);
   63         b->dev = dev;
   64 
   65         return b;
   66 }
   67 
   68 void
   69 sndbuf_destroy(struct snd_dbuf *b)
   70 {
   71         free(b, M_DEVBUF);
   72 }
   73 
   74 static void
   75 sndbuf_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
   76 {
   77         struct snd_dbuf *b = (struct snd_dbuf *)arg;
   78 
   79         if (bootverbose) {
   80                 device_printf(b->dev, "sndbuf_setmap %lx, %lx; ", (unsigned long)segs->ds_addr,
   81                        (unsigned long)segs->ds_len);
   82                 printf("%p -> %lx\n", b->buf, (unsigned long)vtophys(b->buf));
   83         }
   84 }
   85 
   86 /*
   87  * Allocate memory for DMA buffer. If the device does not use DMA transfers,
   88  * the driver can call malloc(9) and sndbuf_setup() itself.
   89  */
   90 int
   91 sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, unsigned int size)
   92 {
   93         b->dmatag = dmatag;
   94         b->maxsize = size;
   95         b->bufsize = b->maxsize;
   96         if (bus_dmamem_alloc(b->dmatag, (void **)&b->buf, BUS_DMA_NOWAIT, &b->dmamap))
   97                 return ENOSPC;
   98         if (bus_dmamap_load(b->dmatag, b->dmamap, b->buf, b->maxsize, sndbuf_setmap, b, 0))
   99                 return ENOSPC;
  100         return sndbuf_resize(b, 2, b->maxsize / 2);
  101 }
  102 
  103 int
  104 sndbuf_setup(struct snd_dbuf *b, void *buf, unsigned int size)
  105 {
  106         b->buf = buf;
  107         b->maxsize = size;
  108         b->bufsize = b->maxsize;
  109         return sndbuf_resize(b, 2, b->maxsize / 2);
  110 }
  111 
  112 void
  113 sndbuf_free(struct snd_dbuf *b)
  114 {
  115         if (b->tmpbuf)
  116                 free(b->tmpbuf, M_DEVBUF);
  117         b->tmpbuf = NULL;
  118 
  119         if (b->dmamap)
  120                 bus_dmamap_unload(b->dmatag, b->dmamap);
  121 
  122         if (b->dmamap && b->buf)
  123                 bus_dmamem_free(b->dmatag, b->buf, b->dmamap);
  124         b->dmamap = NULL;
  125         b->buf = NULL;
  126 }
  127 
  128 int
  129 sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
  130 {
  131         if (b->maxsize == 0)
  132                 return 0;
  133         if (blkcnt == 0)
  134                 blkcnt = b->blkcnt;
  135         if (blksz == 0)
  136                 blksz = b->blksz;
  137         if (blkcnt < 2 || blksz < 16 || (blkcnt * blksz > b->maxsize))
  138                 return EINVAL;
  139         if (blkcnt == b->blkcnt && blksz == b->blksz)
  140                 return 0;
  141         b->blkcnt = blkcnt;
  142         b->blksz = blksz;
  143         b->bufsize = blkcnt * blksz;
  144         if (b->tmpbuf)
  145                 free(b->tmpbuf, M_DEVBUF);
  146         b->tmpbuf = malloc(b->bufsize, M_DEVBUF, M_NOWAIT);
  147         sndbuf_reset(b);
  148         return 0;
  149 }
  150 
  151 int
  152 sndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
  153 {
  154         u_int8_t *buf, *tmpbuf, *f1, *f2;
  155         unsigned int bufsize;
  156 
  157         if (blkcnt < 2 || blksz < 16)
  158                 return EINVAL;
  159 
  160         bufsize = blksz * blkcnt;
  161 
  162 
  163         buf = malloc(bufsize, M_DEVBUF, M_NOWAIT);
  164         if (buf == NULL)
  165                 return ENOMEM;
  166 
  167         tmpbuf = malloc(bufsize, M_DEVBUF, M_NOWAIT);
  168         if (tmpbuf == NULL) {
  169                 free(buf, M_DEVBUF);
  170                 return ENOMEM;
  171         }
  172 
  173         b->blkcnt = blkcnt;
  174         b->blksz = blksz;
  175         b->bufsize = bufsize;
  176         b->maxsize = bufsize;
  177         f1 = b->buf;
  178         f2 = b->tmpbuf;
  179         b->buf = buf;
  180         b->tmpbuf = tmpbuf;
  181 
  182         if (f1)
  183                 free(f1, M_DEVBUF);
  184         if (f2)
  185                 free(f2, M_DEVBUF);
  186 
  187         sndbuf_reset(b);
  188         return 0;
  189 }
  190 
  191 void
  192 sndbuf_clear(struct snd_dbuf *b, unsigned int length)
  193 {
  194         int i;
  195         u_char data, *p;
  196 
  197         if (length == 0)
  198                 return;
  199         if (length > b->bufsize)
  200                 length = b->bufsize;
  201 
  202         if (b->fmt & AFMT_SIGNED)
  203                 data = 0x00;
  204         else
  205                 data = 0x80;
  206 
  207         i = sndbuf_getfreeptr(b);
  208         p = sndbuf_getbuf(b);
  209         while (length > 0) {
  210                 p[i] = data;
  211                 length--;
  212                 i++;
  213                 if (i >= b->bufsize)
  214                         i = 0;
  215         }
  216 }
  217 
  218 void
  219 sndbuf_fillsilence(struct snd_dbuf *b)
  220 {
  221         int i;
  222         u_char data, *p;
  223 
  224         if (b->fmt & AFMT_SIGNED)
  225                 data = 0x00;
  226         else
  227                 data = 0x80;
  228 
  229         i = 0;
  230         p = sndbuf_getbuf(b);
  231         while (i < b->bufsize)
  232                 p[i++] = data;
  233         b->rp = 0;
  234         b->rl = b->bufsize;
  235 }
  236 
  237 void
  238 sndbuf_reset(struct snd_dbuf *b)
  239 {
  240         b->hp = 0;
  241         b->rp = 0;
  242         b->rl = 0;
  243         b->dl = 0;
  244         b->prev_total = 0;
  245         b->total = 0;
  246         b->xrun = 0;
  247         if (b->buf && b->bufsize > 0)
  248                 sndbuf_clear(b, b->bufsize);
  249 }
  250 
  251 u_int32_t
  252 sndbuf_getfmt(struct snd_dbuf *b)
  253 {
  254         return b->fmt;
  255 }
  256 
  257 int
  258 sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt)
  259 {
  260         b->fmt = fmt;
  261         b->bps = 1;
  262         b->bps <<= (b->fmt & AFMT_STEREO)? 1 : 0;
  263         b->bps <<= (b->fmt & AFMT_16BIT)? 1 : 0;
  264         b->bps <<= (b->fmt & AFMT_32BIT)? 2 : 0;
  265         return 0;
  266 }
  267 
  268 unsigned int
  269 sndbuf_getspd(struct snd_dbuf *b)
  270 {
  271         return b->spd;
  272 }
  273 
  274 void
  275 sndbuf_setspd(struct snd_dbuf *b, unsigned int spd)
  276 {
  277         b->spd = spd;
  278 }
  279 
  280 unsigned int
  281 sndbuf_getalign(struct snd_dbuf *b)
  282 {
  283         static int align[] = {0, 1, 1, 2, 2, 2, 2, 3};
  284 
  285         return align[b->bps - 1];
  286 }
  287 
  288 unsigned int
  289 sndbuf_getblkcnt(struct snd_dbuf *b)
  290 {
  291         return b->blkcnt;
  292 }
  293 
  294 void
  295 sndbuf_setblkcnt(struct snd_dbuf *b, unsigned int blkcnt)
  296 {
  297         b->blkcnt = blkcnt;
  298 }
  299 
  300 unsigned int
  301 sndbuf_getblksz(struct snd_dbuf *b)
  302 {
  303         return b->blksz;
  304 }
  305 
  306 void
  307 sndbuf_setblksz(struct snd_dbuf *b, unsigned int blksz)
  308 {
  309         b->blksz = blksz;
  310 }
  311 
  312 unsigned int
  313 sndbuf_getbps(struct snd_dbuf *b)
  314 {
  315         return b->bps;
  316 }
  317 
  318 void *
  319 sndbuf_getbuf(struct snd_dbuf *b)
  320 {
  321         return b->buf;
  322 }
  323 
  324 void *
  325 sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs)
  326 {
  327         KASSERT(ofs < b->bufsize, ("%s: ofs invalid %d", __func__, ofs));
  328 
  329         return b->buf + ofs;
  330 }
  331 
  332 unsigned int
  333 sndbuf_getsize(struct snd_dbuf *b)
  334 {
  335         return b->bufsize;
  336 }
  337 
  338 unsigned int
  339 sndbuf_getmaxsize(struct snd_dbuf *b)
  340 {
  341         return b->maxsize;
  342 }
  343 
  344 unsigned int
  345 sndbuf_runsz(struct snd_dbuf *b)
  346 {
  347         return b->dl;
  348 }
  349 
  350 void
  351 sndbuf_setrun(struct snd_dbuf *b, int go)
  352 {
  353         b->dl = go? b->blksz : 0;
  354 }
  355 
  356 struct selinfo *
  357 sndbuf_getsel(struct snd_dbuf *b)
  358 {
  359         return &b->sel;
  360 }
  361 
  362 /************************************************************/
  363 unsigned int
  364 sndbuf_getxrun(struct snd_dbuf *b)
  365 {
  366         SNDBUF_LOCKASSERT(b);
  367 
  368         return b->xrun;
  369 }
  370 
  371 void
  372 sndbuf_setxrun(struct snd_dbuf *b, unsigned int cnt)
  373 {
  374         SNDBUF_LOCKASSERT(b);
  375 
  376         b->xrun = cnt;
  377 }
  378 
  379 unsigned int
  380 sndbuf_gethwptr(struct snd_dbuf *b)
  381 {
  382         SNDBUF_LOCKASSERT(b);
  383 
  384         return b->hp;
  385 }
  386 
  387 void
  388 sndbuf_sethwptr(struct snd_dbuf *b, unsigned int ptr)
  389 {
  390         SNDBUF_LOCKASSERT(b);
  391 
  392         b->hp = ptr;
  393 }
  394 
  395 unsigned int
  396 sndbuf_getready(struct snd_dbuf *b)
  397 {
  398         SNDBUF_LOCKASSERT(b);
  399         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  400 
  401         return b->rl;
  402 }
  403 
  404 unsigned int
  405 sndbuf_getreadyptr(struct snd_dbuf *b)
  406 {
  407         SNDBUF_LOCKASSERT(b);
  408         KASSERT((b->rp >= 0) && (b->rp <= b->bufsize), ("%s: b->rp invalid %d", __func__, b->rp));
  409 
  410         return b->rp;
  411 }
  412 
  413 unsigned int
  414 sndbuf_getfree(struct snd_dbuf *b)
  415 {
  416         SNDBUF_LOCKASSERT(b);
  417         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  418 
  419         return b->bufsize - b->rl;
  420 }
  421 
  422 unsigned int
  423 sndbuf_getfreeptr(struct snd_dbuf *b)
  424 {
  425         SNDBUF_LOCKASSERT(b);
  426         KASSERT((b->rp >= 0) && (b->rp <= b->bufsize), ("%s: b->rp invalid %d", __func__, b->rp));
  427         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  428 
  429         return (b->rp + b->rl) % b->bufsize;
  430 }
  431 
  432 unsigned int
  433 sndbuf_getblocks(struct snd_dbuf *b)
  434 {
  435         SNDBUF_LOCKASSERT(b);
  436 
  437         return b->total / b->blksz;
  438 }
  439 
  440 unsigned int
  441 sndbuf_getprevblocks(struct snd_dbuf *b)
  442 {
  443         SNDBUF_LOCKASSERT(b);
  444 
  445         return b->prev_total / b->blksz;
  446 }
  447 
  448 unsigned int
  449 sndbuf_gettotal(struct snd_dbuf *b)
  450 {
  451         SNDBUF_LOCKASSERT(b);
  452 
  453         return b->total;
  454 }
  455 
  456 void
  457 sndbuf_updateprevtotal(struct snd_dbuf *b)
  458 {
  459         SNDBUF_LOCKASSERT(b);
  460 
  461         b->prev_total = b->total;
  462 }
  463 
  464 /************************************************************/
  465 
  466 int
  467 sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count)
  468 {
  469         int l;
  470 
  471         KASSERT(count <= sndbuf_getfree(b), ("%s: count %d > free %d", __func__, count, sndbuf_getfree(b)));
  472         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  473         b->total += count;
  474         if (from != NULL) {
  475                 while (count > 0) {
  476                         l = MIN(count, sndbuf_getsize(b) - sndbuf_getfreeptr(b));
  477                         bcopy(from, sndbuf_getbufofs(b, sndbuf_getfreeptr(b)), l);
  478                         from += l;
  479                         b->rl += l;
  480                         count -= l;
  481                 }
  482         } else
  483                 b->rl += count;
  484         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d, count %d", __func__, b->rl, count));
  485 
  486         return 0;
  487 }
  488 
  489 int
  490 sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count)
  491 {
  492         int l;
  493 
  494         KASSERT(count <= sndbuf_getready(b), ("%s: count %d > ready %d", __func__, count, sndbuf_getready(b)));
  495         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  496         if (to != NULL) {
  497                 while (count > 0) {
  498                         l = MIN(count, sndbuf_getsize(b) - sndbuf_getreadyptr(b));
  499                         bcopy(sndbuf_getbufofs(b, sndbuf_getreadyptr(b)), to, l);
  500                         to += l;
  501                         b->rl -= l;
  502                         b->rp = (b->rp + l) % b->bufsize;
  503                         count -= l;
  504                 }
  505         } else {
  506                 b->rl -= count;
  507                 b->rp = (b->rp + count) % b->bufsize;
  508         }
  509         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d, count %d", __func__, b->rl, count));
  510 
  511         return 0;
  512 }
  513 
  514 int
  515 sndbuf_uiomove(struct snd_dbuf *b, struct uio *uio, unsigned int count)
  516 {
  517         int x, c, p, rd, err;
  518 
  519         err = 0;
  520         rd = (uio->uio_rw == UIO_READ)? 1 : 0;
  521         if (count > uio->uio_resid)
  522                 return EINVAL;
  523 
  524         if (count > (rd? sndbuf_getready(b) : sndbuf_getfree(b))) {
  525                 return EINVAL;
  526         }
  527 
  528         while (err == 0 && count > 0) {
  529                 p = rd? sndbuf_getreadyptr(b) : sndbuf_getfreeptr(b);
  530                 c = MIN(count, sndbuf_getsize(b) - p);
  531                 x = uio->uio_resid;
  532                 err = uiomove(sndbuf_getbufofs(b, p), c, uio);
  533                 x -= uio->uio_resid;
  534                 count -= x;
  535                 x = rd? sndbuf_dispose(b, NULL, x) : sndbuf_acquire(b, NULL, x);
  536         }
  537 
  538         return 0;
  539 }
  540 
  541 /* count is number of bytes we want added to destination buffer */
  542 int
  543 sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *channel, struct pcm_feeder *feeder, unsigned int count)
  544 {
  545         KASSERT(count > 0, ("can't feed 0 bytes"));
  546 
  547         if (sndbuf_getfree(to) < count)
  548                 return EINVAL;
  549 
  550         count = FEEDER_FEED(feeder, channel, to->tmpbuf, count, from);
  551         if (count)
  552                 sndbuf_acquire(to, to->tmpbuf, count);
  553         /* the root feeder has called sndbuf_dispose(from, , bytes fetched) */
  554 
  555         return 0;
  556 }
  557 
  558 /************************************************************/
  559 
  560 void
  561 sndbuf_dump(struct snd_dbuf *b, char *s, u_int32_t what)
  562 {
  563         printf("%s: [", s);
  564         if (what & 0x01)
  565                 printf(" bufsize: %d, maxsize: %d", b->bufsize, b->maxsize);
  566         if (what & 0x02)
  567                 printf(" dl: %d, rp: %d, rl: %d, hp: %d", b->dl, b->rp, b->rl, b->hp);
  568         if (what & 0x04)
  569                 printf(" total: %d, prev_total: %d, xrun: %d", b->total, b->prev_total, b->xrun);
  570         if (what & 0x08)
  571                 printf(" fmt: 0x%x, spd: %d", b->fmt, b->spd);
  572         if (what & 0x10)
  573                 printf(" blksz: %d, blkcnt: %d, flags: 0x%x", b->blksz, b->blkcnt, b->flags);
  574         printf(" ]\n");
  575 }
  576 
  577 /************************************************************/
  578 u_int32_t
  579 sndbuf_getflags(struct snd_dbuf *b)
  580 {
  581         return b->flags;
  582 }
  583 
  584 void
  585 sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on)
  586 {
  587         b->flags &= ~flags;
  588         if (on)
  589                 b->flags |= flags;
  590 }
  591 
  592 /************************************************************/
  593 
  594 int
  595 sndbuf_isadmasetup(struct snd_dbuf *b, struct resource *drq)
  596 {
  597         /* should do isa_dma_acquire/isa_dma_release here */
  598         if (drq == NULL) {
  599                 b->isadmachan = -1;
  600         } else {
  601                 sndbuf_setflags(b, SNDBUF_F_ISADMA, 1);
  602                 b->isadmachan = rman_get_start(drq);
  603         }
  604         return 0;
  605 }
  606 
  607 int
  608 sndbuf_isadmasetdir(struct snd_dbuf *b, int dir)
  609 {
  610         KASSERT(b, ("sndbuf_isadmasetdir called with b == NULL"));
  611         KASSERT(sndbuf_getflags(b) & SNDBUF_F_ISADMA, ("sndbuf_isadmasetdir called on non-ISA buffer"));
  612 
  613         b->dir = (dir == PCMDIR_PLAY)? ISADMA_WRITE : ISADMA_READ;
  614         return 0;
  615 }
  616 
  617 void
  618 sndbuf_isadma(struct snd_dbuf *b, int go)
  619 {
  620         KASSERT(b, ("sndbuf_isadma called with b == NULL"));
  621         KASSERT(sndbuf_getflags(b) & SNDBUF_F_ISADMA, ("sndbuf_isadma called on non-ISA buffer"));
  622 
  623         switch (go) {
  624         case PCMTRIG_START:
  625                 /* isa_dmainit(b->chan, size); */
  626                 isa_dmastart(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->isadmachan);
  627                 break;
  628 
  629         case PCMTRIG_STOP:
  630         case PCMTRIG_ABORT:
  631                 isa_dmastop(b->isadmachan);
  632                 isa_dmadone(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->isadmachan);
  633                 break;
  634         }
  635 
  636         DEB(printf("buf 0x%p ISA DMA %s, channel %d\n",
  637                 b,
  638                 (go == PCMTRIG_START)? "started" : "stopped",
  639                 b->isadmachan));
  640 }
  641 
  642 int
  643 sndbuf_isadmaptr(struct snd_dbuf *b)
  644 {
  645         int i;
  646 
  647         KASSERT(b, ("sndbuf_isadmaptr called with b == NULL"));
  648         KASSERT(sndbuf_getflags(b) & SNDBUF_F_ISADMA, ("sndbuf_isadmaptr called on non-ISA buffer"));
  649 
  650         if (!sndbuf_runsz(b))
  651                 return 0;
  652         i = isa_dmastatus(b->isadmachan);
  653         KASSERT(i >= 0, ("isa_dmastatus returned %d", i));
  654         return b->bufsize - i;
  655 }
  656 
  657 void
  658 sndbuf_isadmabounce(struct snd_dbuf *b)
  659 {
  660         KASSERT(b, ("sndbuf_isadmabounce called with b == NULL"));
  661         KASSERT(sndbuf_getflags(b) & SNDBUF_F_ISADMA, ("sndbuf_isadmabounce called on non-ISA buffer"));
  662 
  663         /* tell isa_dma to bounce data in/out */
  664 }
  665 

Cache object: 387de371ed8b36aeadf28873464ae59f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.