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: stable/4/sys/dev/sound/pcm/buffer.c 95264 2002-04-22 15:49:36Z 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_WAITOK);
  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         if (blkcnt < 2 || blksz < 16)
  155                 return EINVAL;
  156 
  157         b->blkcnt = blkcnt;
  158         b->blksz = blksz;
  159 
  160         b->maxsize = blkcnt * blksz;
  161         b->bufsize = b->maxsize;
  162 
  163         if (b->buf)
  164                 free(b->buf, M_DEVBUF);
  165         b->buf = malloc(b->bufsize, M_DEVBUF, M_WAITOK);
  166         if (b->buf == NULL)
  167                 return ENOMEM;
  168 
  169         if (b->tmpbuf)
  170                 free(b->tmpbuf, M_DEVBUF);
  171         b->tmpbuf = malloc(b->bufsize, M_DEVBUF, M_WAITOK);
  172         if (b->tmpbuf == NULL)
  173                 return ENOMEM;
  174 
  175         sndbuf_reset(b);
  176         return 0;
  177 }
  178 
  179 void
  180 sndbuf_clear(struct snd_dbuf *b, unsigned int length)
  181 {
  182         int i;
  183         u_char data, *p;
  184 
  185         if (length == 0)
  186                 return;
  187         if (length > b->bufsize)
  188                 length = b->bufsize;
  189 
  190         if (b->fmt & AFMT_SIGNED)
  191                 data = 0x00;
  192         else
  193                 data = 0x80;
  194 
  195         i = sndbuf_getfreeptr(b);
  196         p = sndbuf_getbuf(b);
  197         while (length > 0) {
  198                 p[i] = data;
  199                 length--;
  200                 i++;
  201                 if (i >= b->bufsize)
  202                         i = 0;
  203         }
  204 }
  205 
  206 void
  207 sndbuf_fillsilence(struct snd_dbuf *b)
  208 {
  209         int i;
  210         u_char data, *p;
  211 
  212         if (b->fmt & AFMT_SIGNED)
  213                 data = 0x00;
  214         else
  215                 data = 0x80;
  216 
  217         i = 0;
  218         p = sndbuf_getbuf(b);
  219         while (i < b->bufsize)
  220                 p[i++] = data;
  221         b->rp = 0;
  222         b->rl = b->bufsize;
  223 }
  224 
  225 void
  226 sndbuf_reset(struct snd_dbuf *b)
  227 {
  228         b->hp = 0;
  229         b->rp = 0;
  230         b->rl = 0;
  231         b->dl = 0;
  232         b->prev_total = 0;
  233         b->total = 0;
  234         b->xrun = 0;
  235         if (b->buf && b->bufsize > 0)
  236                 sndbuf_clear(b, b->bufsize);
  237 }
  238 
  239 u_int32_t
  240 sndbuf_getfmt(struct snd_dbuf *b)
  241 {
  242         return b->fmt;
  243 }
  244 
  245 int
  246 sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt)
  247 {
  248         b->fmt = fmt;
  249         b->bps = 1;
  250         b->bps <<= (b->fmt & AFMT_STEREO)? 1 : 0;
  251         b->bps <<= (b->fmt & AFMT_16BIT)? 1 : 0;
  252         b->bps <<= (b->fmt & AFMT_32BIT)? 2 : 0;
  253         return 0;
  254 }
  255 
  256 unsigned int
  257 sndbuf_getspd(struct snd_dbuf *b)
  258 {
  259         return b->spd;
  260 }
  261 
  262 void
  263 sndbuf_setspd(struct snd_dbuf *b, unsigned int spd)
  264 {
  265         b->spd = spd;
  266 }
  267 
  268 unsigned int
  269 sndbuf_getalign(struct snd_dbuf *b)
  270 {
  271         static int align[] = {0, 1, 1, 2, 2, 2, 2, 3};
  272 
  273         return align[b->bps - 1];
  274 }
  275 
  276 unsigned int
  277 sndbuf_getblkcnt(struct snd_dbuf *b)
  278 {
  279         return b->blkcnt;
  280 }
  281 
  282 void
  283 sndbuf_setblkcnt(struct snd_dbuf *b, unsigned int blkcnt)
  284 {
  285         b->blkcnt = blkcnt;
  286 }
  287 
  288 unsigned int
  289 sndbuf_getblksz(struct snd_dbuf *b)
  290 {
  291         return b->blksz;
  292 }
  293 
  294 void
  295 sndbuf_setblksz(struct snd_dbuf *b, unsigned int blksz)
  296 {
  297         b->blksz = blksz;
  298 }
  299 
  300 unsigned int
  301 sndbuf_getbps(struct snd_dbuf *b)
  302 {
  303         return b->bps;
  304 }
  305 
  306 void *
  307 sndbuf_getbuf(struct snd_dbuf *b)
  308 {
  309         return b->buf;
  310 }
  311 
  312 void *
  313 sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs)
  314 {
  315         KASSERT(ofs < b->bufsize, ("%s: ofs invalid %d", __func__, ofs));
  316 
  317         return b->buf + ofs;
  318 }
  319 
  320 unsigned int
  321 sndbuf_getsize(struct snd_dbuf *b)
  322 {
  323         return b->bufsize;
  324 }
  325 
  326 unsigned int
  327 sndbuf_getmaxsize(struct snd_dbuf *b)
  328 {
  329         return b->maxsize;
  330 }
  331 
  332 unsigned int
  333 sndbuf_runsz(struct snd_dbuf *b)
  334 {
  335         return b->dl;
  336 }
  337 
  338 void
  339 sndbuf_setrun(struct snd_dbuf *b, int go)
  340 {
  341         b->dl = go? b->blksz : 0;
  342 }
  343 
  344 struct selinfo *
  345 sndbuf_getsel(struct snd_dbuf *b)
  346 {
  347         return &b->sel;
  348 }
  349 
  350 /************************************************************/
  351 unsigned int
  352 sndbuf_getxrun(struct snd_dbuf *b)
  353 {
  354         SNDBUF_LOCKASSERT(b);
  355 
  356         return b->xrun;
  357 }
  358 
  359 void
  360 sndbuf_setxrun(struct snd_dbuf *b, unsigned int cnt)
  361 {
  362         SNDBUF_LOCKASSERT(b);
  363 
  364         b->xrun = cnt;
  365 }
  366 
  367 unsigned int
  368 sndbuf_gethwptr(struct snd_dbuf *b)
  369 {
  370         SNDBUF_LOCKASSERT(b);
  371 
  372         return b->hp;
  373 }
  374 
  375 void
  376 sndbuf_sethwptr(struct snd_dbuf *b, unsigned int ptr)
  377 {
  378         SNDBUF_LOCKASSERT(b);
  379 
  380         b->hp = ptr;
  381 }
  382 
  383 unsigned int
  384 sndbuf_getready(struct snd_dbuf *b)
  385 {
  386         SNDBUF_LOCKASSERT(b);
  387         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  388 
  389         return b->rl;
  390 }
  391 
  392 unsigned int
  393 sndbuf_getreadyptr(struct snd_dbuf *b)
  394 {
  395         SNDBUF_LOCKASSERT(b);
  396         KASSERT((b->rp >= 0) && (b->rp <= b->bufsize), ("%s: b->rp invalid %d", __func__, b->rp));
  397 
  398         return b->rp;
  399 }
  400 
  401 unsigned int
  402 sndbuf_getfree(struct snd_dbuf *b)
  403 {
  404         SNDBUF_LOCKASSERT(b);
  405         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  406 
  407         return b->bufsize - b->rl;
  408 }
  409 
  410 unsigned int
  411 sndbuf_getfreeptr(struct snd_dbuf *b)
  412 {
  413         SNDBUF_LOCKASSERT(b);
  414         KASSERT((b->rp >= 0) && (b->rp <= b->bufsize), ("%s: b->rp invalid %d", __func__, b->rp));
  415         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  416 
  417         return (b->rp + b->rl) % b->bufsize;
  418 }
  419 
  420 unsigned int
  421 sndbuf_getblocks(struct snd_dbuf *b)
  422 {
  423         SNDBUF_LOCKASSERT(b);
  424 
  425         return b->total / b->blksz;
  426 }
  427 
  428 unsigned int
  429 sndbuf_getprevblocks(struct snd_dbuf *b)
  430 {
  431         SNDBUF_LOCKASSERT(b);
  432 
  433         return b->prev_total / b->blksz;
  434 }
  435 
  436 unsigned int
  437 sndbuf_gettotal(struct snd_dbuf *b)
  438 {
  439         SNDBUF_LOCKASSERT(b);
  440 
  441         return b->total;
  442 }
  443 
  444 void
  445 sndbuf_updateprevtotal(struct snd_dbuf *b)
  446 {
  447         SNDBUF_LOCKASSERT(b);
  448 
  449         b->prev_total = b->total;
  450 }
  451 
  452 /************************************************************/
  453 
  454 int
  455 sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count)
  456 {
  457         int l;
  458 
  459         KASSERT(count <= sndbuf_getfree(b), ("%s: count %d > free %d", __func__, count, sndbuf_getfree(b)));
  460         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  461         b->total += count;
  462         if (from != NULL) {
  463                 while (count > 0) {
  464                         l = MIN(count, sndbuf_getsize(b) - sndbuf_getfreeptr(b));
  465                         bcopy(from, sndbuf_getbufofs(b, sndbuf_getfreeptr(b)), l);
  466                         from += l;
  467                         b->rl += l;
  468                         count -= l;
  469                 }
  470         } else
  471                 b->rl += count;
  472         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d, count %d", __func__, b->rl, count));
  473 
  474         return 0;
  475 }
  476 
  477 int
  478 sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count)
  479 {
  480         int l;
  481 
  482         KASSERT(count <= sndbuf_getready(b), ("%s: count %d > ready %d", __func__, count, sndbuf_getready(b)));
  483         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
  484         if (to != NULL) {
  485                 while (count > 0) {
  486                         l = MIN(count, sndbuf_getsize(b) - sndbuf_getreadyptr(b));
  487                         bcopy(sndbuf_getbufofs(b, sndbuf_getreadyptr(b)), to, l);
  488                         to += l;
  489                         b->rl -= l;
  490                         b->rp = (b->rp + l) % b->bufsize;
  491                         count -= l;
  492                 }
  493         } else {
  494                 b->rl -= count;
  495                 b->rp = (b->rp + count) % b->bufsize;
  496         }
  497         KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d, count %d", __func__, b->rl, count));
  498 
  499         return 0;
  500 }
  501 
  502 int
  503 sndbuf_uiomove(struct snd_dbuf *b, struct uio *uio, unsigned int count)
  504 {
  505         int x, c, p, rd, err;
  506 
  507         err = 0;
  508         rd = (uio->uio_rw == UIO_READ)? 1 : 0;
  509         if (count > uio->uio_resid)
  510                 return EINVAL;
  511 
  512         if (count > (rd? sndbuf_getready(b) : sndbuf_getfree(b))) {
  513                 return EINVAL;
  514         }
  515 
  516         while (err == 0 && count > 0) {
  517                 p = rd? sndbuf_getreadyptr(b) : sndbuf_getfreeptr(b);
  518                 c = MIN(count, sndbuf_getsize(b) - p);
  519                 x = uio->uio_resid;
  520                 err = uiomove(sndbuf_getbufofs(b, p), c, uio);
  521                 x -= uio->uio_resid;
  522                 count -= x;
  523                 x = rd? sndbuf_dispose(b, NULL, x) : sndbuf_acquire(b, NULL, x);
  524         }
  525 
  526         return 0;
  527 }
  528 
  529 /* count is number of bytes we want added to destination buffer */
  530 int
  531 sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *channel, struct pcm_feeder *feeder, unsigned int count)
  532 {
  533         KASSERT(count > 0, ("can't feed 0 bytes"));
  534 
  535         if (sndbuf_getfree(to) < count)
  536                 return EINVAL;
  537 
  538         count = FEEDER_FEED(feeder, channel, to->tmpbuf, count, from);
  539         if (count)
  540                 sndbuf_acquire(to, to->tmpbuf, count);
  541         /* the root feeder has called sndbuf_dispose(from, , bytes fetched) */
  542 
  543         return 0;
  544 }
  545 
  546 /************************************************************/
  547 
  548 void
  549 sndbuf_dump(struct snd_dbuf *b, char *s, u_int32_t what)
  550 {
  551         printf("%s: [", s);
  552         if (what & 0x01)
  553                 printf(" bufsize: %d, maxsize: %d", b->bufsize, b->maxsize);
  554         if (what & 0x02)
  555                 printf(" dl: %d, rp: %d, rl: %d, hp: %d", b->dl, b->rp, b->rl, b->hp);
  556         if (what & 0x04)
  557                 printf(" total: %d, prev_total: %d, xrun: %d", b->total, b->prev_total, b->xrun);
  558         if (what & 0x08)
  559                 printf(" fmt: 0x%x, spd: %d", b->fmt, b->spd);
  560         if (what & 0x10)
  561                 printf(" blksz: %d, blkcnt: %d, flags: 0x%x", b->blksz, b->blkcnt, b->flags);
  562         printf(" ]\n");
  563 }
  564 
  565 /************************************************************/
  566 u_int32_t
  567 sndbuf_getflags(struct snd_dbuf *b)
  568 {
  569         return b->flags;
  570 }
  571 
  572 void
  573 sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on)
  574 {
  575         b->flags &= ~flags;
  576         if (on)
  577                 b->flags |= flags;
  578 }
  579 
  580 /************************************************************/
  581 
  582 int
  583 sndbuf_isadmasetup(struct snd_dbuf *b, struct resource *drq)
  584 {
  585         /* should do isa_dma_acquire/isa_dma_release here */
  586         if (drq == NULL) {
  587                 b->isadmachan = -1;
  588         } else {
  589                 sndbuf_setflags(b, SNDBUF_F_ISADMA, 1);
  590                 b->isadmachan = rman_get_start(drq);
  591         }
  592         return 0;
  593 }
  594 
  595 int
  596 sndbuf_isadmasetdir(struct snd_dbuf *b, int dir)
  597 {
  598         KASSERT(b, ("sndbuf_isadmasetdir called with b == NULL"));
  599         KASSERT(sndbuf_getflags(b) & SNDBUF_F_ISADMA, ("sndbuf_isadmasetdir called on non-ISA buffer"));
  600 
  601         b->dir = (dir == PCMDIR_PLAY)? ISADMA_WRITE : ISADMA_READ;
  602         return 0;
  603 }
  604 
  605 void
  606 sndbuf_isadma(struct snd_dbuf *b, int go)
  607 {
  608         KASSERT(b, ("sndbuf_isadma called with b == NULL"));
  609         KASSERT(sndbuf_getflags(b) & SNDBUF_F_ISADMA, ("sndbuf_isadma called on non-ISA buffer"));
  610 
  611         switch (go) {
  612         case PCMTRIG_START:
  613                 /* isa_dmainit(b->chan, size); */
  614                 isa_dmastart(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->isadmachan);
  615                 break;
  616 
  617         case PCMTRIG_STOP:
  618         case PCMTRIG_ABORT:
  619                 isa_dmastop(b->isadmachan);
  620                 isa_dmadone(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->isadmachan);
  621                 break;
  622         }
  623 
  624         DEB(printf("buf 0x%p ISA DMA %s, channel %d\n",
  625                 b,
  626                 (go == PCMTRIG_START)? "started" : "stopped",
  627                 b->isadmachan));
  628 }
  629 
  630 int
  631 sndbuf_isadmaptr(struct snd_dbuf *b)
  632 {
  633         int i;
  634 
  635         KASSERT(b, ("sndbuf_isadmaptr called with b == NULL"));
  636         KASSERT(sndbuf_getflags(b) & SNDBUF_F_ISADMA, ("sndbuf_isadmaptr called on non-ISA buffer"));
  637 
  638         if (!sndbuf_runsz(b))
  639                 return 0;
  640         i = isa_dmastatus(b->isadmachan);
  641         KASSERT(i >= 0, ("isa_dmastatus returned %d", i));
  642         return b->bufsize - i;
  643 }
  644 
  645 void
  646 sndbuf_isadmabounce(struct snd_dbuf *b)
  647 {
  648         KASSERT(b, ("sndbuf_isadmabounce called with b == NULL"));
  649         KASSERT(sndbuf_getflags(b) & SNDBUF_F_ISADMA, ("sndbuf_isadmabounce called on non-ISA buffer"));
  650 
  651         /* tell isa_dma to bounce data in/out */
  652 }
  653 

Cache object: 1a0b3f164be5dbfac67fae24f1063f14


[ 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.