Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ieee1394 New Feature: Add isochronous stream input r...



details:   https://anonhg.NetBSD.org/src/rev/fc6179fe818a
branches:  trunk
changeset: 512804:fc6179fe818a
user:      haya <haya%NetBSD.org@localhost>
date:      Tue Jul 17 11:01:03 2001 +0000

description:
New Feature: Add isochronous stream input routine.  This feature has
been tested on i386.  It does not have any interface for useland to
get isochoronous stream.  The isochoronous acquisition interface
should be determined.

diffstat:

 sys/dev/ieee1394/fwohci.c      |  395 +++++++++++++++++++++++++++++++++++++---
 sys/dev/ieee1394/fwohcivar.h   |   22 +-
 sys/dev/ieee1394/ieee1394reg.h |    3 +-
 3 files changed, 379 insertions(+), 41 deletions(-)

diffs (truncated from 691 to 300 lines):

diff -r 9c1d548fa467 -r fc6179fe818a sys/dev/ieee1394/fwohci.c
--- a/sys/dev/ieee1394/fwohci.c Tue Jul 17 10:56:53 2001 +0000
+++ b/sys/dev/ieee1394/fwohci.c Tue Jul 17 11:01:03 2001 +0000
@@ -1,5 +1,7 @@
-/*     $NetBSD: fwohci.c,v 1.39 2001/07/02 11:12:09 onoe Exp $ */
-
+/*     $NetBSD: fwohci.c,v 1.40 2001/07/17 11:01:03 haya Exp $ */
+
+#define DOUBLEBUF 1
+#define NO_THREAD 1
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -43,6 +45,11 @@
  * Atsushi Onoe <onoe%netbsd.org@localhost>.
  */
 
+/*
+ * The first version to support isochronous acquisition part is wrtten
+ * by HAYAKAWA Koichi <haya%netbsd.org@localhost>.
+ */
+
 #include "opt_inet.h"
 
 #include <sys/param.h>
@@ -90,7 +97,7 @@
 static void fwohci_desc_put(struct fwohci_softc *, struct fwohci_desc *, int);
 
 static int  fwohci_ctx_alloc(struct fwohci_softc *, struct fwohci_ctx **,
-    int, int);
+    int, int, int);
 static void fwohci_ctx_free(struct fwohci_softc *, struct fwohci_ctx *);
 static void fwohci_ctx_init(struct fwohci_softc *, struct fwohci_ctx *);
 
@@ -147,8 +154,11 @@
 static int  fwohci_if_inreg(struct device *, u_int32_t, u_int32_t,
     void (*)(struct device *, struct mbuf *));
 static int  fwohci_if_input(struct fwohci_softc *, void *, struct fwohci_pkt *);
+static int  fwohci_if_input_iso(struct fwohci_softc *, void *, struct fwohci_pkt *);
 static int  fwohci_if_output(struct device *, struct mbuf *,
     void (*)(struct device *, struct mbuf *));
+static int fwohci_if_setiso(struct device *, int, int, int,
+    void (*)(struct device *, struct mbuf *));
 static int  fwohci_read(struct ieee1394_abuf *);
 static int  fwohci_write(struct ieee1394_abuf *);
 static int  fwohci_read_resp(struct fwohci_softc *, void *, struct fwohci_pkt *);
@@ -186,6 +196,11 @@
        evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ev,
            sc->sc_sc1394.sc1394_dev.dv_xname, "intr");
 
+       evcnt_attach_dynamic(&sc->sc_isocnt, EVCNT_TYPE_MISC, ev,
+           sc->sc_sc1394.sc1394_dev.dv_xname, "iso");
+       evcnt_attach_dynamic(&sc->sc_isopktcnt, EVCNT_TYPE_MISC, ev,
+           sc->sc_sc1394.sc1394_dev.dv_xname, "isopackets");
+
        /*
         * Wait for reset completion
         */
@@ -263,6 +278,34 @@
        return 0;
 }
 
+static int
+fwohci_if_setiso(struct device *self, int channel, int tag, int direction,
+    void (*handler)(struct device *, struct mbuf *))
+{
+       struct fwohci_softc *sc = (struct fwohci_softc *)self;
+       int retval;
+       int s;
+
+       if (direction == 1) {
+               return EIO;
+       }
+
+       s = splnet();
+       retval = fwohci_handler_set(sc, IEEE1394_TCODE_STREAM_DATA,
+           channel, tag, fwohci_if_input_iso, handler);
+       splx(s);
+
+       if (!retval) {
+               printf("%s: dummy iso handler set\n",
+                   sc->sc_sc1394.sc1394_dev.dv_xname);
+       } else {
+               printf("%s: dummy iso handler cannot set\n",
+                   sc->sc_sc1394.sc1394_dev.dv_xname);
+       }
+
+       return retval;
+}
+
 int
 fwohci_intr(void *arg)
 {
@@ -318,9 +361,38 @@
                        OHCI_CSR_WRITE(sc, OHCI_REG_IsoXmitIntEventClear, iso);
                }
                if (intmask & OHCI_Int_IsochRx) {
+#if NO_THREAD
+                       int i;
+                       int asyncstream = 0;
+#endif
+
                        iso = OHCI_CSR_READ(sc, OHCI_REG_IsoRecvIntEventClear);
                        OHCI_CSR_WRITE(sc, OHCI_REG_IsoRecvIntEventClear, iso);
+#if NO_THREAD
+                       for (i = 0; i < sc->sc_isoctx; i++) {
+                               if ((iso & (1<<i)) && sc->sc_ctx_ir[i] != NULL) {
+                                       if (sc->sc_ctx_ir[i]->fc_type == FWOHCI_CTX_ISO_SINGLE) {
+                                               asyncstream |= (1 << i);
+                                               continue;
+                                       }
+                                       bus_dmamap_sync(sc->sc_dmat,
+                                           sc->sc_ddmamap,
+                                           0, sizeof(struct fwohci_desc) * sc->sc_descsize,
+                                           BUS_DMASYNC_PREREAD);
+                                       sc->sc_isocnt.ev_count++;
+
+                                       fwohci_ir_input(sc, sc->sc_ctx_ir[i]);
+                               }
+                       }
+                       if (asyncstream != 0) {
+                               sc->sc_iso |= asyncstream;
+                       } else {
+                               /* all iso intr is pure isochronous */
+                               sc->sc_intmask &= ~OHCI_Int_IsochRx;
+                       }
+#else
                        sc->sc_iso |= iso;
+#endif /* NO_THREAD */
                }
 
                if (!progress) {
@@ -368,11 +440,13 @@
         * Allocate DMA Context
         */
        fwohci_ctx_alloc(sc, &sc->sc_ctx_arrq, OHCI_BUF_ARRQ_CNT,
-           OHCI_CTX_ASYNC_RX_REQUEST);
+           OHCI_CTX_ASYNC_RX_REQUEST, FWOHCI_CTX_ASYNC);
        fwohci_ctx_alloc(sc, &sc->sc_ctx_arrs, OHCI_BUF_ARRS_CNT,
-           OHCI_CTX_ASYNC_RX_RESPONSE);
-       fwohci_ctx_alloc(sc, &sc->sc_ctx_atrq, 0, OHCI_CTX_ASYNC_TX_REQUEST);
-       fwohci_ctx_alloc(sc, &sc->sc_ctx_atrs, 0, OHCI_CTX_ASYNC_TX_RESPONSE);
+           OHCI_CTX_ASYNC_RX_RESPONSE, FWOHCI_CTX_ASYNC);
+       fwohci_ctx_alloc(sc, &sc->sc_ctx_atrq, 0, OHCI_CTX_ASYNC_TX_REQUEST,
+           FWOHCI_CTX_ASYNC);
+       fwohci_ctx_alloc(sc, &sc->sc_ctx_atrs, 0, OHCI_CTX_ASYNC_TX_RESPONSE,
+           FWOHCI_CTX_ASYNC);
        sc->sc_ctx_ir = malloc(sizeof(sc->sc_ctx_ir[0]) * sc->sc_isoctx,
            M_DEVBUF, M_WAITOK);
        for (i = 0; i < sc->sc_isoctx; i++)
@@ -388,6 +462,7 @@
 
        sc->sc_sc1394.sc1394_ifinreg = fwohci_if_inreg;
        sc->sc_sc1394.sc1394_ifoutput = fwohci_if_output;
+       sc->sc_sc1394.sc1394_ifsetiso = fwohci_if_setiso;
 
        /*
         * establish hooks for shutdown and suspend/resume 
@@ -476,8 +551,10 @@
                        splx(s);
                        for (i = 0; i < sc->sc_isoctx; i++) {
                                if ((iso & (1 << i)) &&
-                                   sc->sc_ctx_ir[i] != NULL)
+                                   sc->sc_ctx_ir[i] != NULL) {
                                        fwohci_ir_input(sc, sc->sc_ctx_ir[i]);
+                                       sc->sc_isocnt.ev_count++;
+                               }
                        }
                }
        }
@@ -855,12 +932,13 @@
  */
 static int
 fwohci_ctx_alloc(struct fwohci_softc *sc, struct fwohci_ctx **fcp,
-    int bufcnt, int ctx)
+    int bufcnt, int ctx, int ctxtype)
 {
        int i, error;
        struct fwohci_ctx *fc;
        struct fwohci_buf *fb;
        struct fwohci_desc *fd;
+       int buf2cnt;
 
        fc = malloc(sizeof(*fc) + sizeof(*fb) * bufcnt, M_DEVBUF, M_WAITOK);
        memset(fc, 0, sizeof(*fc) + sizeof(*fb) * bufcnt);
@@ -869,6 +947,16 @@
        fc->fc_ctx = ctx;
        fc->fc_bufcnt = bufcnt;
        fb = (struct fwohci_buf *)&fc[1];
+#if DOUBLEBUF
+       TAILQ_INIT(&fc->fc_buf2); /* for isochronous */
+       if (ctxtype == FWOHCI_CTX_ISO_MULTI) {
+               buf2cnt = bufcnt/2;
+               bufcnt -= buf2cnt;
+               if (buf2cnt == 0) {
+                       panic("cannot allocate iso buffer");
+               }
+       }
+#endif
        for (i = 0; i < bufcnt; i++, fb++) {
                if ((error = fwohci_buf_alloc(sc, fb)) != 0)
                        goto fail;
@@ -885,6 +973,33 @@
                fd->fd_data = fb->fb_dmamap->dm_segs[0].ds_addr;
                TAILQ_INSERT_TAIL(&fc->fc_buf, fb, fb_list);
        }
+#if DOUBLEBUF
+       if (ctxtype == FWOHCI_CTX_ISO_MULTI) {
+               for (i = bufcnt; i < bufcnt + buf2cnt; i++, fb++) {
+                       if ((error = fwohci_buf_alloc(sc, fb)) != 0)
+                               goto fail;
+                       if ((fd = fwohci_desc_get(sc, 1)) == NULL) {
+                               error = ENOBUFS;
+                               goto fail;
+                       }
+                       fb->fb_desc = fd;
+                       fb->fb_daddr = sc->sc_ddmamap->dm_segs[0].ds_addr +
+                           ((caddr_t)fd - (caddr_t)sc->sc_desc);
+                       bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
+                           (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc),
+                           BUS_DMASYNC_PREWRITE);
+                       fd->fd_flags = OHCI_DESC_INPUT | OHCI_DESC_STATUS |
+                           OHCI_DESC_INTR_ALWAYS | OHCI_DESC_BRANCH;
+                       fd->fd_reqcount = fb->fb_dmamap->dm_segs[0].ds_len;
+                       fd->fd_data = fb->fb_dmamap->dm_segs[0].ds_addr;
+                       TAILQ_INSERT_TAIL(&fc->fc_buf2, fb, fb_list);
+                       bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
+                           (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc),
+                           BUS_DMASYNC_POSTWRITE);
+               }
+       }
+#endif /* DOUBLEBUF */
+       fc->fc_type = ctxtype;
        *fcp = fc;
        return 0;
 
@@ -914,6 +1029,14 @@
                        fwohci_desc_put(sc, fb->fb_desc, 1);
                fwohci_buf_free(sc, fb);
        }
+#if DOUBLEBUF
+       while ((fb = TAILQ_FIRST(&fc->fc_buf2)) != NULL) {
+               TAILQ_REMOVE(&fc->fc_buf2, fb, fb_list);
+               if (fb->fb_desc)
+                       fwohci_desc_put(sc, fb->fb_desc, 1);
+               fwohci_buf_free(sc, fb);
+       }
+#endif /* DOUBLEBUF */
        free(fc, M_DEVBUF);
 }
 
@@ -933,9 +1056,25 @@
                fd->fd_rescount = fd->fd_reqcount;
        }
 
+#if DOUBLEBUF
+       for (fb = TAILQ_FIRST(&fc->fc_buf2); fb != NULL; fb = nfb) {
+               bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
+                   (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc),
+                   BUS_DMASYNC_PREWRITE);
+               nfb = TAILQ_NEXT(fb, fb_list);
+               fb->fb_off = 0;
+               fd = fb->fb_desc;
+               fd->fd_branch = (nfb != NULL) ? (nfb->fb_daddr | 1) : 0;
+               fd->fd_rescount = fd->fd_reqcount;
+               bus_dmamap_sync(sc->sc_dmat, sc->sc_ddmamap,
+                   (caddr_t)fd - (caddr_t)sc->sc_desc, sizeof(struct fwohci_desc),
+                   BUS_DMASYNC_POSTWRITE);
+       }
+#endif /* DOUBLEBUF */
+
        n = fc->fc_ctx;
        fb = TAILQ_FIRST(&fc->fc_buf);
-       if (fc->fc_isoch) {
+       if (fc->fc_type != FWOHCI_CTX_ASYNC) {
                OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_CommandPtr,
                    fb->fb_daddr | 1);
                OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextControlClear,
@@ -945,6 +1084,11 @@
                    OHCI_CTXCTL_RX_DUAL_BUFFER_MODE);
                OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextControlSet,
                    OHCI_CTXCTL_RX_ISOCH_HEADER);
+               if (fc->fc_type == FWOHCI_CTX_ISO_MULTI) {
+                       OHCI_SYNC_RX_DMA_WRITE(sc, n,
+                           OHCI_SUBREG_ContextControlSet,
+                           OHCI_CTXCTL_RX_BUFFER_FILL);
+               }
                fh = LIST_FIRST(&fc->fc_handler);
                OHCI_SYNC_RX_DMA_WRITE(sc, n, OHCI_SUBREG_ContextMatch,
                    (OHCI_CTXMATCH_TAG0 << fh->fh_key2) | fh->fh_key1);
@@ -1102,23 +1246,43 @@
 {
        struct fwohci_buf *fb, *tfb;
 
-       while ((fb = TAILQ_FIRST(&fc->fc_buf)) != NULL) {
-               if (fc->fc_isoch) {
-                       if (fb->fb_off == 0)
-                               break;
-               } else {
-                       if (fb->fb_off != fb->fb_desc->fd_reqcount ||



Home | Main Index | Thread Index | Old Index