/* * ioctl support. */ int fw_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, fw_proc *td) { struct firewire_comm *fc; struct fw_drv1 *d; int i, len, err = 0; struct fw_device *fwdev; struct fw_bind *fwb; struct fw_xferq *ir, *it; struct fw_xfer *xfer; struct fw_pkt *fp; struct fw_devinfo *devinfo; void *ptr; struct fw_devlstreq *fwdevlst = (struct fw_devlstreq *)data; struct fw_asyreq *asyreq = (struct fw_asyreq *)data; struct fw_isochreq *ichreq = (struct fw_isochreq *)data; struct fw_isobufreq *ibufreq = (struct fw_isobufreq *)data; struct fw_asybindreq *bindreq = (struct fw_asybindreq *)data; struct fw_crom_buf *crom_buf = (struct fw_crom_buf *)data; if (DEV_FWMEM(dev)) return fwmem_ioctl(dev, cmd, data, flag, td); if (!data) return (EINVAL); d = dev->si_drv1; fc = d->fc; ir = d->ir; it = d->it; switch (cmd) { case FW_STSTREAM: if (it == NULL) { i = fw_open_isodma(fc, /* tx */1); if (i < 0) { err = EBUSY; break; } it = fc->it[i]; err = fwdev_allocbuf(fc, it, &d->bufreq.tx); if (err) { it->flag &= ~FWXFERQ_OPEN; break; } } it->flag &= ~0xff; it->flag |= (0x3f & ichreq->ch); it->flag |= ((0x3 & ichreq->tag) << 6); d->it = it; break; case FW_GTSTREAM: if (it != NULL) { ichreq->ch = it->flag & 0x3f; ichreq->tag = it->flag >> 2 & 0x3; } else
static void fwe_init(void *arg) { struct fwe_softc *fwe = ((struct fwe_eth_softc *)arg)->fwe; struct firewire_comm *fc; struct ifnet *ifp = fwe->eth_softc.ifp; struct fw_xferq *xferq; struct fw_xfer *xfer; struct mbuf *m; int i; FWEDEBUG(ifp, "initializing\n"); /* XXX keep promiscoud mode */ ifp->if_flags |= IFF_PROMISC; fc = fwe->fd.fc; if (fwe->dma_ch < 0) { fwe->dma_ch = fw_open_isodma(fc, /* tx */0); if (fwe->dma_ch < 0) return; xferq = fc->ir[fwe->dma_ch]; xferq->flag |= FWXFERQ_EXTBUF | FWXFERQ_HANDLER | FWXFERQ_STREAM; fwe->stream_ch = stream_ch; fwe->pkt_hdr.mode.stream.chtag = fwe->stream_ch; xferq->flag &= ~0xff; xferq->flag |= fwe->stream_ch & 0xff; /* register fwe_input handler */ xferq->sc = (caddr_t) fwe; xferq->hand = fwe_as_input; xferq->bnchunk = rx_queue_len; xferq->bnpacket = 1; xferq->psize = MCLBYTES; xferq->queued = 0; xferq->buf = NULL; xferq->bulkxfer = (struct fw_bulkxfer *) malloc( sizeof(struct fw_bulkxfer) * xferq->bnchunk, M_FWE, M_WAITOK); if (xferq->bulkxfer == NULL) { printf("if_fwe: malloc failed\n"); return; } STAILQ_INIT(&xferq->stvalid); STAILQ_INIT(&xferq->stfree); STAILQ_INIT(&xferq->stdma); xferq->stproc = NULL; for (i = 0; i < xferq->bnchunk; i ++) { m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR); xferq->bulkxfer[i].mbuf = m; m->m_len = m->m_pkthdr.len = m->m_ext.ext_size; STAILQ_INSERT_TAIL(&xferq->stfree, &xferq->bulkxfer[i], link); } STAILQ_INIT(&fwe->xferlist); for (i = 0; i < TX_MAX_QUEUE; i++) { xfer = fw_xfer_alloc(M_FWE); if (xfer == NULL) break; xfer->send.spd = tx_speed; xfer->fc = fwe->fd.fc; xfer->sc = (caddr_t)fwe; xfer->hand = fwe_output_callback; STAILQ_INSERT_TAIL(&fwe->xferlist, xfer, link); } } else xferq = fc->ir[fwe->dma_ch]; /* start dma */ if ((xferq->flag & FWXFERQ_RUNNING) == 0) fc->irx_enable(fc, fwe->dma_ch); #if defined(__FreeBSD__) ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; #else ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; #endif #if 0 /* attempt to start output */ fwe_start(ifp); #endif }
static void fwip_init(void *arg) { struct fwip_softc *fwip = ((struct fwip_eth_softc *)arg)->fwip; struct firewire_comm *fc; struct ifnet *ifp = fwip->fw_softc.fwip_ifp; struct fw_xferq *xferq; struct fw_xfer *xfer; struct mbuf *m; int i; FWIPDEBUG(ifp, "initializing\n"); fc = fwip->fd.fc; #define START 0 if (fwip->dma_ch < 0) { fwip->dma_ch = fw_open_isodma(fc, /* tx */0); if (fwip->dma_ch < 0) return; xferq = fc->ir[fwip->dma_ch]; xferq->flag |= FWXFERQ_EXTBUF | FWXFERQ_HANDLER | FWXFERQ_STREAM; xferq->flag &= ~0xff; xferq->flag |= broadcast_channel & 0xff; /* register fwip_input handler */ xferq->sc = (caddr_t) fwip; xferq->hand = fwip_stream_input; xferq->bnchunk = rx_queue_len; xferq->bnpacket = 1; xferq->psize = MCLBYTES; xferq->queued = 0; xferq->buf = NULL; xferq->bulkxfer = (struct fw_bulkxfer *) malloc( sizeof(struct fw_bulkxfer) * xferq->bnchunk, M_FWIP, M_WAITOK); if (xferq->bulkxfer == NULL) { printf("if_fwip: malloc failed\n"); return; } STAILQ_INIT(&xferq->stvalid); STAILQ_INIT(&xferq->stfree); STAILQ_INIT(&xferq->stdma); xferq->stproc = NULL; for (i = 0; i < xferq->bnchunk; i ++) { m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR); xferq->bulkxfer[i].mbuf = m; m->m_len = m->m_pkthdr.len = m->m_ext.ext_size; STAILQ_INSERT_TAIL(&xferq->stfree, &xferq->bulkxfer[i], link); } fwip->fwb.start = INET_FIFO; fwip->fwb.end = INET_FIFO + 16384; /* S3200 packet size */ /* pre-allocate xfer */ STAILQ_INIT(&fwip->fwb.xferlist); for (i = 0; i < rx_queue_len; i ++) { xfer = fw_xfer_alloc(M_FWIP); if (xfer == NULL) break; m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR); xfer->recv.payload = mtod(m, uint32_t *); xfer->recv.pay_len = MCLBYTES; xfer->hand = fwip_unicast_input; xfer->fc = fc; xfer->sc = (caddr_t)fwip; xfer->mbuf = m; STAILQ_INSERT_TAIL(&fwip->fwb.xferlist, xfer, link); } fw_bindadd(fc, &fwip->fwb); STAILQ_INIT(&fwip->xferlist); for (i = 0; i < TX_MAX_QUEUE; i++) { xfer = fw_xfer_alloc(M_FWIP); if (xfer == NULL) break; xfer->send.spd = tx_speed; xfer->fc = fwip->fd.fc; xfer->sc = (caddr_t)fwip; xfer->hand = fwip_output_callback; STAILQ_INSERT_TAIL(&fwip->xferlist, xfer, link); } } else