Hello All,
        Please test a pcm patch that releases the channel lock around
calls to uio move.  This is a more complete patch than the previous
one as it also does the _read routine.  I will ask the RE to commit
this if I hear a couple of "it works".

Pointed out by: Artur Poplawski
Explained by:   Don Lewis

        --Mat

-- 
        sig machine broken
--- channel.c   Sun Nov  9 04:17:22 2003
+++ /sys/dev/sound/pcm/channel.c        Wed Nov 26 13:50:20 2003
@@ -250,6 +250,8 @@
 {
        int ret, timeout, newsize, count, sz;
        struct snd_dbuf *bs = c->bufsoft;
+       void *off;
+       int t, x,togo,p;
 
        CHN_LOCKASSERT(c);
        /*
@@ -291,7 +293,22 @@
                        sz = MIN(sz, buf->uio_resid);
                        KASSERT(sz > 0, ("confusion in chn_write"));
                        /* printf("sz: %d\n", sz); */
+#if 0
                        ret = sndbuf_uiomove(bs, buf, sz);
+#else
+                       togo = sz;
+                       while (ret == 0 && togo> 0) {
+                               p = sndbuf_getfreeptr(bs);
+                               t = MIN(togo, sndbuf_getsize(bs) - p);
+                               off = sndbuf_getbufofs(bs, p);
+                               CHN_UNLOCK(c);
+                               ret = uiomove(off, t, buf);
+                               CHN_LOCK(c);
+                               togo -= t;
+                               x = sndbuf_acquire(bs, NULL, t);
+                       }
+                       ret = 0;
+#endif
                        if (ret == 0 && !(c->flags & CHN_F_TRIGGERED))
                                chn_start(c, 0);
                }
@@ -395,6 +412,8 @@
 {
        int             ret, timeout, sz, count;
        struct snd_dbuf       *bs = c->bufsoft;
+       void *off;
+       int t, x,togo,p;
 
        CHN_LOCKASSERT(c);
        if (!(c->flags & CHN_F_TRIGGERED))
@@ -406,7 +425,22 @@
                sz = MIN(buf->uio_resid, sndbuf_getready(bs));
 
                if (sz > 0) {
+#if 0
                        ret = sndbuf_uiomove(bs, buf, sz);
+#else
+                       togo = sz;
+                       while (ret == 0 && togo> 0) {
+                               p = sndbuf_getreadyptr(bs);
+                               t = MIN(togo, sndbuf_getsize(bs) - p);
+                               off = sndbuf_getbufofs(bs, p);
+                               CHN_UNLOCK(c);
+                               ret = uiomove(off, t, buf);
+                               CHN_LOCK(c);
+                               togo -= t;
+                               x = sndbuf_dispose(bs, NULL, t);
+                       }
+                       ret = 0;
+#endif
                } else {
                        if (c->flags & CHN_F_NBIO) {
                                ret = EWOULDBLOCK;
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to