Index: stable/10/sys/dev/firewire/fwdev.c =================================================================== --- stable/10/sys/dev/firewire/fwdev.c (revision 299229) +++ stable/10/sys/dev/firewire/fwdev.c (revision 299230) @@ -1,1001 +1,1000 @@ /*- * Copyright (c) 2003 Hidetoshi Shimokawa * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the acknowledgement as bellow: * * This product includes software developed by K. Kobayashi and H. Shimokawa * * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ * */ #include #include #include #include #if defined(__DragonFly__) || __FreeBSD_version < 500000 #include #else #include #endif #include #include #include #include #include #include #include #include #ifdef __DragonFly__ #include "firewire.h" #include "firewirereg.h" #include "fwdma.h" #include "fwmem.h" #include "iec68113.h" #else #include #include #include #include #include #endif #define FWNODE_INVAL 0xffff static d_open_t fw_open; static d_close_t fw_close; static d_ioctl_t fw_ioctl; static d_poll_t fw_poll; static d_read_t fw_read; /* for Isochronous packet */ static d_write_t fw_write; static d_mmap_t fw_mmap; static d_strategy_t fw_strategy; struct cdevsw firewire_cdevsw = { #ifdef __DragonFly__ #define CDEV_MAJOR 127 "fw", CDEV_MAJOR, D_MEM, NULL, 0, fw_open, fw_close, fw_read, fw_write, fw_ioctl, fw_poll, fw_mmap, fw_strategy, nodump, nopsize, #elif __FreeBSD_version >= 500104 .d_version = D_VERSION, .d_open = fw_open, .d_close = fw_close, .d_read = fw_read, .d_write = fw_write, .d_ioctl = fw_ioctl, .d_poll = fw_poll, .d_mmap = fw_mmap, .d_strategy = fw_strategy, .d_name = "fw", - .d_flags = D_MEM #else #define CDEV_MAJOR 127 fw_open, fw_close, fw_read, fw_write, fw_ioctl, fw_poll, fw_mmap, fw_strategy, "fw", CDEV_MAJOR, nodump, nopsize, D_MEM, -1 #endif }; struct fw_drv1 { struct firewire_comm *fc; struct fw_xferq *ir; struct fw_xferq *it; struct fw_isobufreq bufreq; STAILQ_HEAD(, fw_bind) binds; STAILQ_HEAD(, fw_xfer) rq; }; static int fwdev_allocbuf(struct firewire_comm *fc, struct fw_xferq *q, struct fw_bufspec *b) { int i; if (q->flag & (FWXFERQ_RUNNING | FWXFERQ_EXTBUF)) return(EBUSY); q->bulkxfer = (struct fw_bulkxfer *) malloc( sizeof(struct fw_bulkxfer) * b->nchunk, M_FW, M_WAITOK); if (q->bulkxfer == NULL) return(ENOMEM); b->psize = roundup2(b->psize, sizeof(uint32_t)); q->buf = fwdma_malloc_multiseg(fc, sizeof(uint32_t), b->psize, b->nchunk * b->npacket, BUS_DMA_WAITOK); if (q->buf == NULL) { free(q->bulkxfer, M_FW); q->bulkxfer = NULL; return(ENOMEM); } q->bnchunk = b->nchunk; q->bnpacket = b->npacket; q->psize = (b->psize + 3) & ~3; q->queued = 0; STAILQ_INIT(&q->stvalid); STAILQ_INIT(&q->stfree); STAILQ_INIT(&q->stdma); q->stproc = NULL; for(i = 0 ; i < q->bnchunk; i++){ q->bulkxfer[i].poffset = i * q->bnpacket; q->bulkxfer[i].mbuf = NULL; STAILQ_INSERT_TAIL(&q->stfree, &q->bulkxfer[i], link); } q->flag &= ~FWXFERQ_MODEMASK; q->flag |= FWXFERQ_STREAM; q->flag |= FWXFERQ_EXTBUF; return (0); } static int fwdev_freebuf(struct fw_xferq *q) { if (q->flag & FWXFERQ_EXTBUF) { if (q->buf != NULL) fwdma_free_multiseg(q->buf); q->buf = NULL; free(q->bulkxfer, M_FW); q->bulkxfer = NULL; q->flag &= ~FWXFERQ_EXTBUF; q->psize = 0; q->maxq = FWMAXQUEUE; } return (0); } static int fw_open (struct cdev *dev, int flags, int fmt, fw_proc *td) { int err = 0; int unit = DEV2UNIT(dev); struct fw_drv1 *d; struct firewire_softc *sc; if (DEV_FWMEM(dev)) return fwmem_open(dev, flags, fmt, td); sc = devclass_get_softc(firewire_devclass, unit); if (sc == NULL) return (ENXIO); FW_GLOCK(sc->fc); if (dev->si_drv1 != NULL) { FW_GUNLOCK(sc->fc); return (EBUSY); } /* set dummy value for allocation */ dev->si_drv1 = (void *)-1; FW_GUNLOCK(sc->fc); dev->si_drv1 = malloc(sizeof(struct fw_drv1), M_FW, M_WAITOK | M_ZERO); if (dev->si_drv1 == NULL) return (ENOMEM); #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 if ((dev->si_flags & SI_NAMED) == 0) { int unit = DEV2UNIT(dev); int sub = DEV2SUB(dev); make_dev(&firewire_cdevsw, dev2unit(dev), UID_ROOT, GID_OPERATOR, 0660, "fw%d.%d", unit, sub); } #endif d = (struct fw_drv1 *)dev->si_drv1; d->fc = sc->fc; STAILQ_INIT(&d->binds); STAILQ_INIT(&d->rq); return err; } static int fw_close (struct cdev *dev, int flags, int fmt, fw_proc *td) { struct firewire_comm *fc; struct fw_drv1 *d; struct fw_xfer *xfer; struct fw_bind *fwb; int err = 0; if (DEV_FWMEM(dev)) return fwmem_close(dev, flags, fmt, td); d = (struct fw_drv1 *)dev->si_drv1; fc = d->fc; /* remove binding */ for (fwb = STAILQ_FIRST(&d->binds); fwb != NULL; fwb = STAILQ_FIRST(&d->binds)) { fw_bindremove(fc, fwb); STAILQ_REMOVE_HEAD(&d->binds, chlist); fw_xferlist_remove(&fwb->xferlist); free(fwb, M_FW); } if (d->ir != NULL) { struct fw_xferq *ir = d->ir; if ((ir->flag & FWXFERQ_OPEN) == 0) return (EINVAL); if (ir->flag & FWXFERQ_RUNNING) { ir->flag &= ~FWXFERQ_RUNNING; fc->irx_disable(fc, ir->dmach); } /* free extbuf */ fwdev_freebuf(ir); /* drain receiving buffer */ for (xfer = STAILQ_FIRST(&ir->q); xfer != NULL; xfer = STAILQ_FIRST(&ir->q)) { ir->queued --; STAILQ_REMOVE_HEAD(&ir->q, link); xfer->resp = 0; fw_xfer_done(xfer); } ir->flag &= ~(FWXFERQ_OPEN | FWXFERQ_MODEMASK | FWXFERQ_CHTAGMASK); d->ir = NULL; } if (d->it != NULL) { struct fw_xferq *it = d->it; if ((it->flag & FWXFERQ_OPEN) == 0) return (EINVAL); if (it->flag & FWXFERQ_RUNNING) { it->flag &= ~FWXFERQ_RUNNING; fc->itx_disable(fc, it->dmach); } /* free extbuf */ fwdev_freebuf(it); it->flag &= ~(FWXFERQ_OPEN | FWXFERQ_MODEMASK | FWXFERQ_CHTAGMASK); d->it = NULL; } free(dev->si_drv1, M_FW); dev->si_drv1 = NULL; return err; } static int fw_read_async(struct fw_drv1 *d, struct uio *uio, int ioflag) { int err = 0, s; struct fw_xfer *xfer; struct fw_bind *fwb; struct fw_pkt *fp; struct tcode_info *tinfo; FW_GLOCK(d->fc); while ((xfer = STAILQ_FIRST(&d->rq)) == NULL && err == 0) err = msleep(&d->rq, FW_GMTX(d->fc), FWPRI, "fwra", 0); if (err != 0) { FW_GUNLOCK(d->fc); return (err); } s = splfw(); STAILQ_REMOVE_HEAD(&d->rq, link); FW_GUNLOCK(xfer->fc); splx(s); fp = &xfer->recv.hdr; #if 0 /* for GASP ?? */ if (fc->irx_post != NULL) fc->irx_post(fc, fp->mode.ld); #endif tinfo = &xfer->fc->tcode[fp->mode.hdr.tcode]; err = uiomove((void *)fp, tinfo->hdr_len, uio); if (err) goto out; err = uiomove((void *)xfer->recv.payload, xfer->recv.pay_len, uio); out: /* recycle this xfer */ fwb = (struct fw_bind *)xfer->sc; fw_xfer_unload(xfer); xfer->recv.pay_len = PAGE_SIZE; FW_GLOCK(xfer->fc); STAILQ_INSERT_TAIL(&fwb->xferlist, xfer, link); FW_GUNLOCK(xfer->fc); return (err); } /* * read request. */ static int fw_read (struct cdev *dev, struct uio *uio, int ioflag) { struct fw_drv1 *d; struct fw_xferq *ir; struct firewire_comm *fc; int err = 0, s, slept = 0; struct fw_pkt *fp; if (DEV_FWMEM(dev)) return (physio(dev, uio, ioflag)); d = (struct fw_drv1 *)dev->si_drv1; fc = d->fc; ir = d->ir; if (ir == NULL) return (fw_read_async(d, uio, ioflag)); if (ir->buf == NULL) return (EIO); FW_GLOCK(fc); readloop: if (ir->stproc == NULL) { /* iso bulkxfer */ ir->stproc = STAILQ_FIRST(&ir->stvalid); if (ir->stproc != NULL) { s = splfw(); STAILQ_REMOVE_HEAD(&ir->stvalid, link); splx(s); ir->queued = 0; } } if (ir->stproc == NULL) { /* no data avaliable */ if (slept == 0) { slept = 1; ir->flag |= FWXFERQ_WAKEUP; err = msleep(ir, FW_GMTX(fc), FWPRI, "fw_read", hz); ir->flag &= ~FWXFERQ_WAKEUP; if (err == 0) goto readloop; } else if (slept == 1) err = EIO; FW_GUNLOCK(fc); return err; } else if(ir->stproc != NULL) { /* iso bulkxfer */ FW_GUNLOCK(fc); fp = (struct fw_pkt *)fwdma_v_addr(ir->buf, ir->stproc->poffset + ir->queued); if(fc->irx_post != NULL) fc->irx_post(fc, fp->mode.ld); if(fp->mode.stream.len == 0){ err = EIO; return err; } err = uiomove((caddr_t)fp, fp->mode.stream.len + sizeof(uint32_t), uio); ir->queued ++; if(ir->queued >= ir->bnpacket){ s = splfw(); STAILQ_INSERT_TAIL(&ir->stfree, ir->stproc, link); splx(s); fc->irx_enable(fc, ir->dmach); ir->stproc = NULL; } if (uio->uio_resid >= ir->psize) { slept = -1; FW_GLOCK(fc); goto readloop; } } return err; } static int fw_write_async(struct fw_drv1 *d, struct uio *uio, int ioflag) { struct fw_xfer *xfer; struct fw_pkt pkt; struct tcode_info *tinfo; int err; bzero(&pkt, sizeof(struct fw_pkt)); if ((err = uiomove((caddr_t)&pkt, sizeof(uint32_t), uio))) return (err); tinfo = &d->fc->tcode[pkt.mode.hdr.tcode]; if ((err = uiomove((caddr_t)&pkt + sizeof(uint32_t), tinfo->hdr_len - sizeof(uint32_t), uio))) return (err); if ((xfer = fw_xfer_alloc_buf(M_FWXFER, uio->uio_resid, PAGE_SIZE/*XXX*/)) == NULL) return (ENOMEM); bcopy(&pkt, &xfer->send.hdr, sizeof(struct fw_pkt)); xfer->send.pay_len = uio->uio_resid; if (uio->uio_resid > 0) { if ((err = uiomove((caddr_t)&xfer->send.payload[0], uio->uio_resid, uio))) goto out; } xfer->fc = d->fc; xfer->sc = NULL; xfer->hand = fw_xferwake; xfer->send.spd = 2 /* XXX */; if ((err = fw_asyreq(xfer->fc, -1, xfer))) goto out; if ((err = fw_xferwait(xfer))) goto out; if (xfer->resp != 0) { err = xfer->resp; goto out; } if (xfer->flag & FWXF_RCVD) { FW_GLOCK(xfer->fc); STAILQ_INSERT_TAIL(&d->rq, xfer, link); FW_GUNLOCK(xfer->fc); return (0); } out: fw_xfer_free(xfer); return (err); } static int fw_write (struct cdev *dev, struct uio *uio, int ioflag) { int err = 0; int s, slept = 0; struct fw_drv1 *d; struct fw_pkt *fp; struct firewire_comm *fc; struct fw_xferq *it; if (DEV_FWMEM(dev)) return (physio(dev, uio, ioflag)); d = (struct fw_drv1 *)dev->si_drv1; fc = d->fc; it = d->it; if (it == NULL) return (fw_write_async(d, uio, ioflag)); if (it->buf == NULL) return (EIO); FW_GLOCK(fc); isoloop: if (it->stproc == NULL) { it->stproc = STAILQ_FIRST(&it->stfree); if (it->stproc != NULL) { s = splfw(); STAILQ_REMOVE_HEAD(&it->stfree, link); splx(s); it->queued = 0; } else if (slept == 0) { slept = 1; #if 0 /* XXX to avoid lock recursion */ err = fc->itx_enable(fc, it->dmach); if (err) goto out; #endif err = msleep(it, FW_GMTX(fc), FWPRI, "fw_write", hz); if (err) goto out; goto isoloop; } else { err = EIO; goto out; } } FW_GUNLOCK(fc); fp = (struct fw_pkt *)fwdma_v_addr(it->buf, it->stproc->poffset + it->queued); err = uiomove((caddr_t)fp, sizeof(struct fw_isohdr), uio); err = uiomove((caddr_t)fp->mode.stream.payload, fp->mode.stream.len, uio); it->queued ++; if (it->queued >= it->bnpacket) { s = splfw(); STAILQ_INSERT_TAIL(&it->stvalid, it->stproc, link); splx(s); it->stproc = NULL; err = fc->itx_enable(fc, it->dmach); } if (uio->uio_resid >= sizeof(struct fw_isohdr)) { slept = 0; FW_GLOCK(fc); goto isoloop; } return err; out: FW_GUNLOCK(fc); return err; } static void fw_hand(struct fw_xfer *xfer) { struct fw_bind *fwb; struct fw_drv1 *d; fwb = (struct fw_bind *)xfer->sc; d = (struct fw_drv1 *)fwb->sc; FW_GLOCK(xfer->fc); STAILQ_INSERT_TAIL(&d->rq, xfer, link); FW_GUNLOCK(xfer->fc); wakeup(&d->rq); } /* * 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 = (struct fw_drv1 *)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 err = EINVAL; break; case FW_SRSTREAM: if (ir == NULL) { i = fw_open_isodma(fc, /* tx */0); if (i < 0) { err = EBUSY; break; } ir = fc->ir[i]; err = fwdev_allocbuf(fc, ir, &d->bufreq.rx); if (err) { ir->flag &= ~FWXFERQ_OPEN; break; } } ir->flag &= ~0xff; ir->flag |= (0x3f & ichreq->ch); ir->flag |= ((0x3 & ichreq->tag) << 6); d->ir = ir; err = fc->irx_enable(fc, ir->dmach); break; case FW_GRSTREAM: if (d->ir != NULL) { ichreq->ch = ir->flag & 0x3f; ichreq->tag = ir->flag >> 2 & 0x3; } else err = EINVAL; break; case FW_SSTBUF: bcopy(ibufreq, &d->bufreq, sizeof(d->bufreq)); break; case FW_GSTBUF: bzero(&ibufreq->rx, sizeof(ibufreq->rx)); if (ir != NULL) { ibufreq->rx.nchunk = ir->bnchunk; ibufreq->rx.npacket = ir->bnpacket; ibufreq->rx.psize = ir->psize; } bzero(&ibufreq->tx, sizeof(ibufreq->tx)); if (it != NULL) { ibufreq->tx.nchunk = it->bnchunk; ibufreq->tx.npacket = it->bnpacket; ibufreq->tx.psize = it->psize; } break; case FW_ASYREQ: { struct tcode_info *tinfo; int pay_len = 0; fp = &asyreq->pkt; tinfo = &fc->tcode[fp->mode.hdr.tcode]; if ((tinfo->flag & FWTI_BLOCK_ASY) != 0) pay_len = MAX(0, asyreq->req.len - tinfo->hdr_len); xfer = fw_xfer_alloc_buf(M_FWXFER, pay_len, PAGE_SIZE/*XXX*/); if (xfer == NULL) return (ENOMEM); switch (asyreq->req.type) { case FWASREQNODE: break; case FWASREQEUI: fwdev = fw_noderesolve_eui64(fc, &asyreq->req.dst.eui); if (fwdev == NULL) { device_printf(fc->bdev, "cannot find node\n"); err = EINVAL; goto out; } fp->mode.hdr.dst = FWLOCALBUS | fwdev->dst; break; case FWASRESTL: /* XXX what's this? */ break; case FWASREQSTREAM: /* nothing to do */ break; } bcopy(fp, (void *)&xfer->send.hdr, tinfo->hdr_len); if (pay_len > 0) bcopy((char *)fp + tinfo->hdr_len, (void *)xfer->send.payload, pay_len); xfer->send.spd = asyreq->req.sped; xfer->hand = fw_xferwake; if ((err = fw_asyreq(fc, -1, xfer)) != 0) goto out; if ((err = fw_xferwait(xfer)) != 0) goto out; if (xfer->resp != 0) { err = EIO; goto out; } if ((tinfo->flag & FWTI_TLABEL) == 0) goto out; /* copy response */ tinfo = &fc->tcode[xfer->recv.hdr.mode.hdr.tcode]; if (xfer->recv.hdr.mode.hdr.tcode == FWTCODE_RRESB || xfer->recv.hdr.mode.hdr.tcode == FWTCODE_LRES) { pay_len = xfer->recv.pay_len; if (asyreq->req.len >= xfer->recv.pay_len + tinfo->hdr_len) { asyreq->req.len = xfer->recv.pay_len + tinfo->hdr_len; } else { err = EINVAL; pay_len = 0; } } else { pay_len = 0; } bcopy(&xfer->recv.hdr, fp, tinfo->hdr_len); bcopy(xfer->recv.payload, (char *)fp + tinfo->hdr_len, pay_len); out: fw_xfer_free_buf(xfer); break; } case FW_IBUSRST: fc->ibr(fc); break; case FW_CBINDADDR: fwb = fw_bindlookup(fc, bindreq->start.hi, bindreq->start.lo); if(fwb == NULL){ err = EINVAL; break; } fw_bindremove(fc, fwb); STAILQ_REMOVE(&d->binds, fwb, fw_bind, chlist); fw_xferlist_remove(&fwb->xferlist); free(fwb, M_FW); break; case FW_SBINDADDR: if(bindreq->len <= 0 ){ err = EINVAL; break; } if(bindreq->start.hi > 0xffff ){ err = EINVAL; break; } fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_FW, M_WAITOK); if(fwb == NULL){ err = ENOMEM; break; } fwb->start = ((u_int64_t)bindreq->start.hi << 32) | bindreq->start.lo; fwb->end = fwb->start + bindreq->len; fwb->sc = (void *)d; STAILQ_INIT(&fwb->xferlist); err = fw_bindadd(fc, fwb); if (err == 0) { fw_xferlist_add(&fwb->xferlist, M_FWXFER, /* XXX */ PAGE_SIZE, PAGE_SIZE, 5, fc, (void *)fwb, fw_hand); STAILQ_INSERT_TAIL(&d->binds, fwb, chlist); } break; case FW_GDEVLST: i = len = 1; /* myself */ devinfo = &fwdevlst->dev[0]; devinfo->dst = fc->nodeid; devinfo->status = 0; /* XXX */ devinfo->eui.hi = fc->eui.hi; devinfo->eui.lo = fc->eui.lo; STAILQ_FOREACH(fwdev, &fc->devices, link) { if(len < FW_MAX_DEVLST){ devinfo = &fwdevlst->dev[len++]; devinfo->dst = fwdev->dst; devinfo->status = (fwdev->status == FWDEVINVAL)?0:1; devinfo->eui.hi = fwdev->eui.hi; devinfo->eui.lo = fwdev->eui.lo; } i++; } fwdevlst->n = i; fwdevlst->info_len = len; break; case FW_GTPMAP: bcopy(fc->topology_map, data, (fc->topology_map->crc_len + 1) * 4); break; case FW_GCROM: STAILQ_FOREACH(fwdev, &fc->devices, link) if (FW_EUI64_EQUAL(fwdev->eui, crom_buf->eui)) break; if (fwdev == NULL) { if (!FW_EUI64_EQUAL(fc->eui, crom_buf->eui)) { err = FWNODE_INVAL; break; } /* myself */ ptr = malloc(CROMSIZE, M_FW, M_WAITOK); len = CROMSIZE; for (i = 0; i < CROMSIZE/4; i++) ((uint32_t *)ptr)[i] = ntohl(fc->config_rom[i]); } else { /* found */ ptr = (void *)&fwdev->csrrom[0]; if (fwdev->rommax < CSRROMOFF) len = 0; else len = fwdev->rommax - CSRROMOFF + 4; } if (crom_buf->len < len) len = crom_buf->len; else crom_buf->len = len; err = copyout(ptr, crom_buf->ptr, len); if (fwdev == NULL) /* myself */ free(ptr, M_FW); break; default: fc->ioctl (dev, cmd, data, flag, td); break; } return err; } int fw_poll(struct cdev *dev, int events, fw_proc *td) { struct fw_xferq *ir; int revents; int tmp; if (DEV_FWMEM(dev)) return fwmem_poll(dev, events, td); ir = ((struct fw_drv1 *)dev->si_drv1)->ir; revents = 0; tmp = POLLIN | POLLRDNORM; if (events & tmp) { if (STAILQ_FIRST(&ir->q) != NULL) revents |= tmp; else selrecord(td, &ir->rsel); } tmp = POLLOUT | POLLWRNORM; if (events & tmp) { /* XXX should be fixed */ revents |= tmp; } return revents; } static int #if defined(__DragonFly__) || __FreeBSD_version < 500102 fw_mmap (struct cdev *dev, vm_offset_t offset, int nproto) #else fw_mmap (struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nproto, vm_memattr_t *memattr) #endif { if (DEV_FWMEM(dev)) #if defined(__DragonFly__) || __FreeBSD_version < 500102 return fwmem_mmap(dev, offset, nproto); #else return fwmem_mmap(dev, offset, paddr, nproto, memattr); #endif return EINVAL; } static void fw_strategy(struct bio *bp) { struct cdev *dev; dev = bp->bio_dev; if (DEV_FWMEM(dev)) { fwmem_strategy(bp); return; } bp->bio_error = EOPNOTSUPP; bp->bio_flags |= BIO_ERROR; bp->bio_resid = bp->bio_bcount; biodone(bp); } int fwdev_makedev(struct firewire_softc *sc) { int err = 0; #if defined(__DragonFly__) || __FreeBSD_version < 500000 cdevsw_add(&firewire_cdevsw); #else struct cdev *d; int unit; unit = device_get_unit(sc->fc->bdev); sc->dev = make_dev(&firewire_cdevsw, MAKEMINOR(0, unit, 0), UID_ROOT, GID_OPERATOR, 0660, "fw%d.%d", unit, 0); d = make_dev(&firewire_cdevsw, MAKEMINOR(FWMEM_FLAG, unit, 0), UID_ROOT, GID_OPERATOR, 0660, "fwmem%d.%d", unit, 0); dev_depends(sc->dev, d); make_dev_alias(sc->dev, "fw%d", unit); make_dev_alias(d, "fwmem%d", unit); #endif return (err); } int fwdev_destroydev(struct firewire_softc *sc) { int err = 0; #if defined(__DragonFly__) || __FreeBSD_version < 500000 cdevsw_remove(&firewire_cdevsw); #else destroy_dev(sc->dev); #endif return (err); } #if defined(__FreeBSD__) && __FreeBSD_version >= 500000 #define NDEVTYPE 2 void fwdev_clone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev) { struct firewire_softc *sc; char *devnames[NDEVTYPE] = {"fw", "fwmem"}; char *subp = NULL; int devflag[NDEVTYPE] = {0, FWMEM_FLAG}; int i, unit = 0, sub = 0; if (*dev != NULL) return; for (i = 0; i < NDEVTYPE; i++) if (dev_stdclone(name, &subp, devnames[i], &unit) == 2) goto found; /* not match */ return; found: if (subp == NULL || *subp++ != '.') return; /* /dev/fwU.S */ while (isdigit(*subp)) { sub *= 10; sub += *subp++ - '0'; } if (*subp != '\0') return; sc = devclass_get_softc(firewire_devclass, unit); if (sc == NULL) return; *dev = make_dev_credf(MAKEDEV_REF, &firewire_cdevsw, MAKEMINOR(devflag[i], unit, sub), cred, UID_ROOT, GID_OPERATOR, 0660, "%s%d.%d", devnames[i], unit, sub); dev_depends(sc->dev, *dev); return; } #endif Index: stable/10/sys/i386/bios/smapi.c =================================================================== --- stable/10/sys/i386/bios/smapi.c (revision 299229) +++ stable/10/sys/i386/bios/smapi.c (revision 299230) @@ -1,321 +1,321 @@ /*- * Copyright (c) 2003 Matthew N. Dodd * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include /* And all this for BIOS_PADDRTOVADDR() */ #include #include #include #include #include #include #define SMAPI_START 0xf0000 #define SMAPI_STEP 0x10 #define SMAPI_OFF 0 #define SMAPI_LEN 4 #define SMAPI_SIG "$SMB" #define RES2HDR(res) ((struct smapi_bios_header *)rman_get_virtual(res)) #define ADDR2HDR(addr) ((struct smapi_bios_header *)BIOS_PADDRTOVADDR(addr)) struct smapi_softc { struct cdev * cdev; device_t dev; struct resource * res; int rid; u_int32_t smapi32_entry; struct smapi_bios_header *header; }; extern u_long smapi32_offset; extern u_short smapi32_segment; devclass_t smapi_devclass; static d_ioctl_t smapi_ioctl; static struct cdevsw smapi_cdevsw = { .d_version = D_VERSION, .d_ioctl = smapi_ioctl, .d_name = "smapi", - .d_flags = D_MEM | D_NEEDGIANT, + .d_flags = D_NEEDGIANT, }; static void smapi_identify(driver_t *, device_t); static int smapi_probe(device_t); static int smapi_attach(device_t); static int smapi_detach(device_t); static int smapi_modevent(module_t, int, void *); static int smapi_header_cksum(struct smapi_bios_header *); extern int smapi32(struct smapi_bios_parameter *, struct smapi_bios_parameter *); extern int smapi32_new(u_long, u_short, struct smapi_bios_parameter *, struct smapi_bios_parameter *); static int smapi_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { struct smapi_softc *sc; int error; error = 0; sc = devclass_get_softc(smapi_devclass, dev2unit(dev)); if (sc == NULL) { error = ENXIO; goto fail; } switch (cmd) { case SMAPIOGHEADER: bcopy((caddr_t)sc->header, data, sizeof(struct smapi_bios_header)); error = 0; break; case SMAPIOCGFUNCTION: smapi32_offset = sc->smapi32_entry; error = smapi32((struct smapi_bios_parameter *)data, (struct smapi_bios_parameter *)data); break; default: error = ENOTTY; } fail: return (error); } static int smapi_header_cksum (struct smapi_bios_header *header) { u_int8_t *ptr; u_int8_t cksum; int i; ptr = (u_int8_t *)header; cksum = 0; for (i = 0; i < header->length; i++) { cksum += ptr[i]; } return (cksum); } static void smapi_identify (driver_t *driver, device_t parent) { device_t child; u_int32_t addr; int length; int rid; if (!device_is_alive(parent)) return; addr = bios_sigsearch(SMAPI_START, SMAPI_SIG, SMAPI_LEN, SMAPI_STEP, SMAPI_OFF); if (addr != 0) { rid = 0; length = ADDR2HDR(addr)->length; child = BUS_ADD_CHILD(parent, 5, "smapi", -1); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length); device_set_desc(child, "SMAPI BIOS"); } return; } static int smapi_probe (device_t dev) { struct resource *res; int rid; int error; error = 0; rid = 0; res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (res == NULL) { device_printf(dev, "Unable to allocate memory resource.\n"); error = ENOMEM; goto bad; } if (smapi_header_cksum(RES2HDR(res))) { device_printf(dev, "SMAPI header checksum failed.\n"); error = ENXIO; goto bad; } bad: if (res) bus_release_resource(dev, SYS_RES_MEMORY, rid, res); return (error); } static int smapi_attach (device_t dev) { struct smapi_softc *sc; int error; sc = device_get_softc(dev); error = 0; sc->dev = dev; sc->rid = 0; sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, RF_ACTIVE); if (sc->res == NULL) { device_printf(dev, "Unable to allocate memory resource.\n"); error = ENOMEM; goto bad; } sc->header = (struct smapi_bios_header *)rman_get_virtual(sc->res); sc->smapi32_entry = (u_int32_t)BIOS_PADDRTOVADDR( sc->header->prot32_segment + sc->header->prot32_offset); sc->cdev = make_dev(&smapi_cdevsw, device_get_unit(sc->dev), UID_ROOT, GID_WHEEL, 0600, "%s%d", smapi_cdevsw.d_name, device_get_unit(sc->dev)); device_printf(dev, "Version: %d.%02d, Length: %d, Checksum: 0x%02x\n", bcd2bin(sc->header->version_major), bcd2bin(sc->header->version_minor), sc->header->length, sc->header->checksum); device_printf(dev, "Information=0x%b\n", sc->header->information, "\020" "\001REAL_VM86" "\002PROTECTED_16" "\003PROTECTED_32"); if (bootverbose) { if (sc->header->information & SMAPI_REAL_VM86) device_printf(dev, "Real/VM86 mode: Segment 0x%04x, Offset 0x%04x\n", sc->header->real16_segment, sc->header->real16_offset); if (sc->header->information & SMAPI_PROT_16BIT) device_printf(dev, "16-bit Protected mode: Segment 0x%08x, Offset 0x%04x\n", sc->header->prot16_segment, sc->header->prot16_offset); if (sc->header->information & SMAPI_PROT_32BIT) device_printf(dev, "32-bit Protected mode: Segment 0x%08x, Offset 0x%08x\n", sc->header->prot32_segment, sc->header->prot32_offset); } return (0); bad: if (sc->res) bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); return (error); } static int smapi_detach (device_t dev) { struct smapi_softc *sc; sc = device_get_softc(dev); destroy_dev(sc->cdev); if (sc->res) bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); return (0); } static int smapi_modevent (module_t mod, int what, void *arg) { device_t * devs; int count; int i; switch (what) { case MOD_LOAD: break; case MOD_UNLOAD: devclass_get_devices(smapi_devclass, &devs, &count); for (i = 0; i < count; i++) { device_delete_child(device_get_parent(devs[i]), devs[i]); } free(devs, M_TEMP); break; default: break; } return (0); } static device_method_t smapi_methods[] = { /* Device interface */ DEVMETHOD(device_identify, smapi_identify), DEVMETHOD(device_probe, smapi_probe), DEVMETHOD(device_attach, smapi_attach), DEVMETHOD(device_detach, smapi_detach), { 0, 0 } }; static driver_t smapi_driver = { "smapi", smapi_methods, sizeof(struct smapi_softc), }; DRIVER_MODULE(smapi, nexus, smapi_driver, smapi_devclass, smapi_modevent, 0); MODULE_VERSION(smapi, 1); Index: stable/10/sys/sys/conf.h =================================================================== --- stable/10/sys/sys/conf.h (revision 299229) +++ stable/10/sys/sys/conf.h (revision 299230) @@ -1,366 +1,366 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * Copyright (c) 2000 * Poul-Henning Kamp. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)conf.h 8.5 (Berkeley) 1/9/95 * $FreeBSD$ */ #ifndef _SYS_CONF_H_ #define _SYS_CONF_H_ #ifdef _KERNEL #include #else #include #endif struct snapdata; struct devfs_dirent; struct cdevsw; struct file; struct cdev { void *si_spare0; u_int si_flags; #define SI_ETERNAL 0x0001 /* never destroyed */ #define SI_ALIAS 0x0002 /* carrier of alias name */ #define SI_NAMED 0x0004 /* make_dev{_alias} has been called */ #define SI_CHEAPCLONE 0x0008 /* can be removed_dev'ed when vnode reclaims */ #define SI_CHILD 0x0010 /* child of another struct cdev **/ #define SI_DUMPDEV 0x0080 /* is kernel dumpdev */ #define SI_CLONELIST 0x0200 /* on a clone list */ #define SI_UNMAPPED 0x0400 /* can handle unmapped I/O */ #define SI_NOSPLIT 0x0800 /* I/O should not be split up */ struct timespec si_atime; struct timespec si_ctime; struct timespec si_mtime; uid_t si_uid; gid_t si_gid; mode_t si_mode; struct ucred *si_cred; /* cached clone-time credential */ int si_drv0; int si_refcount; LIST_ENTRY(cdev) si_list; LIST_ENTRY(cdev) si_clone; LIST_HEAD(, cdev) si_children; LIST_ENTRY(cdev) si_siblings; struct cdev *si_parent; struct mount *si_mountpt; void *si_drv1, *si_drv2; struct cdevsw *si_devsw; int si_iosize_max; /* maximum I/O size (for physio &al) */ u_long si_usecount; u_long si_threadcount; union { struct snapdata *__sid_snapdata; } __si_u; char si_name[SPECNAMELEN + 1]; }; #define si_snapdata __si_u.__sid_snapdata #ifdef _KERNEL /* * Definitions of device driver entry switches */ struct bio; struct buf; struct thread; struct uio; struct knote; struct clonedevs; struct vm_object; struct vnode; /* * Note: d_thread_t is provided as a transition aid for those drivers * that treat struct proc/struct thread as an opaque data type and * exist in substantially the same form in both 4.x and 5.x. Writers * of drivers that dips into the d_thread_t structure should use * struct thread or struct proc as appropriate for the version of the * OS they are using. It is provided in lieu of each device driver * inventing its own way of doing this. While it does violate style(9) * in a number of ways, this violation is deemed to be less * important than the benefits that a uniform API between releases * gives. * * Users of struct thread/struct proc that aren't device drivers should * not use d_thread_t. */ typedef struct thread d_thread_t; typedef int d_open_t(struct cdev *dev, int oflags, int devtype, struct thread *td); typedef int d_fdopen_t(struct cdev *dev, int oflags, struct thread *td, struct file *fp); typedef int d_close_t(struct cdev *dev, int fflag, int devtype, struct thread *td); typedef void d_strategy_t(struct bio *bp); typedef int d_ioctl_t(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td); typedef int d_read_t(struct cdev *dev, struct uio *uio, int ioflag); typedef int d_write_t(struct cdev *dev, struct uio *uio, int ioflag); typedef int d_poll_t(struct cdev *dev, int events, struct thread *td); typedef int d_kqfilter_t(struct cdev *dev, struct knote *kn); typedef int d_mmap_t(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr); typedef int d_mmap_single_t(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size, struct vm_object **object, int nprot); typedef void d_purge_t(struct cdev *dev); typedef int dumper_t( void *_priv, /* Private to the driver. */ void *_virtual, /* Virtual (mapped) address. */ vm_offset_t _physical, /* Physical address of virtual. */ off_t _offset, /* Byte-offset to write at. */ size_t _length); /* Number of bytes to dump. */ #endif /* _KERNEL */ /* * Types for d_flags. */ #define D_TAPE 0x0001 #define D_DISK 0x0002 #define D_TTY 0x0004 -#define D_MEM 0x0008 +#define D_MEM 0x0008 /* /dev/(k)mem */ #ifdef _KERNEL #define D_TYPEMASK 0xffff /* * Flags for d_flags which the drivers can set. */ #define D_TRACKCLOSE 0x00080000 /* track all closes */ #define D_MMAP_ANON 0x00100000 /* special treatment in vm_mmap.c */ #define D_NEEDGIANT 0x00400000 /* driver want Giant */ #define D_NEEDMINOR 0x00800000 /* driver uses clone_create() */ /* * Version numbers. */ #define D_VERSION_00 0x20011966 #define D_VERSION_01 0x17032005 /* Add d_uid,gid,mode & kind */ #define D_VERSION_02 0x28042009 /* Add d_mmap_single */ #define D_VERSION_03 0x17122009 /* d_mmap takes memattr,vm_ooffset_t */ #define D_VERSION D_VERSION_03 /* * Flags used for internal housekeeping */ #define D_INIT 0x80000000 /* cdevsw initialized */ /* * Character device switch table */ struct cdevsw { int d_version; u_int d_flags; const char *d_name; d_open_t *d_open; d_fdopen_t *d_fdopen; d_close_t *d_close; d_read_t *d_read; d_write_t *d_write; d_ioctl_t *d_ioctl; d_poll_t *d_poll; d_mmap_t *d_mmap; d_strategy_t *d_strategy; dumper_t *d_dump; d_kqfilter_t *d_kqfilter; d_purge_t *d_purge; d_mmap_single_t *d_mmap_single; int32_t d_spare0[3]; void *d_spare1[3]; /* These fields should not be messed with by drivers */ LIST_HEAD(, cdev) d_devs; int d_spare2; union { struct cdevsw *gianttrick; SLIST_ENTRY(cdevsw) postfree_list; } __d_giant; }; #define d_gianttrick __d_giant.gianttrick #define d_postfree_list __d_giant.postfree_list struct module; struct devsw_module_data { int (*chainevh)(struct module *, int, void *); /* next handler */ void *chainarg; /* arg for next event handler */ /* Do not initialize fields hereafter */ }; #define DEV_MODULE_ORDERED(name, evh, arg, ord) \ static moduledata_t name##_mod = { \ #name, \ evh, \ arg \ }; \ DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, ord) #define DEV_MODULE(name, evh, arg) \ DEV_MODULE_ORDERED(name, evh, arg, SI_ORDER_MIDDLE) void clone_setup(struct clonedevs **cdp); void clone_cleanup(struct clonedevs **); #define CLONE_UNITMASK 0xfffff #define CLONE_FLAG0 (CLONE_UNITMASK + 1) int clone_create(struct clonedevs **, struct cdevsw *, int *unit, struct cdev **dev, int extra); #define MAKEDEV_REF 0x01 #define MAKEDEV_WHTOUT 0x02 #define MAKEDEV_NOWAIT 0x04 #define MAKEDEV_WAITOK 0x08 #define MAKEDEV_ETERNAL 0x10 #define MAKEDEV_CHECKNAME 0x20 struct make_dev_args { size_t mda_size; int mda_flags; struct cdevsw *mda_devsw; struct ucred *mda_cr; uid_t mda_uid; gid_t mda_gid; int mda_mode; int mda_unit; void *mda_si_drv1; void *mda_si_drv2; }; void make_dev_args_init_impl(struct make_dev_args *_args, size_t _sz); #define make_dev_args_init(a) \ make_dev_args_init_impl((a), sizeof(struct make_dev_args)) int count_dev(struct cdev *_dev); void delist_dev(struct cdev *_dev); void destroy_dev(struct cdev *_dev); int destroy_dev_sched(struct cdev *dev); int destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg); void destroy_dev_drain(struct cdevsw *csw); void drain_dev_clone_events(void); struct cdevsw *dev_refthread(struct cdev *_dev, int *_ref); struct cdevsw *devvn_refthread(struct vnode *vp, struct cdev **devp, int *_ref); void dev_relthread(struct cdev *_dev, int _ref); void dev_depends(struct cdev *_pdev, struct cdev *_cdev); void dev_ref(struct cdev *dev); void dev_refl(struct cdev *dev); void dev_rel(struct cdev *dev); void dev_strategy(struct cdev *dev, struct buf *bp); void dev_strategy_csw(struct cdev *dev, struct cdevsw *csw, struct buf *bp); struct cdev *make_dev(struct cdevsw *_devsw, int _unit, uid_t _uid, gid_t _gid, int _perms, const char *_fmt, ...) __printflike(6, 7); struct cdev *make_dev_cred(struct cdevsw *_devsw, int _unit, struct ucred *_cr, uid_t _uid, gid_t _gid, int _perms, const char *_fmt, ...) __printflike(7, 8); struct cdev *make_dev_credf(int _flags, struct cdevsw *_devsw, int _unit, struct ucred *_cr, uid_t _uid, gid_t _gid, int _mode, const char *_fmt, ...) __printflike(8, 9); int make_dev_p(int _flags, struct cdev **_cdev, struct cdevsw *_devsw, struct ucred *_cr, uid_t _uid, gid_t _gid, int _mode, const char *_fmt, ...) __printflike(8, 9); int make_dev_s(struct make_dev_args *_args, struct cdev **_cdev, const char *_fmt, ...) __printflike(3, 4); struct cdev *make_dev_alias(struct cdev *_pdev, const char *_fmt, ...) __printflike(2, 3); int make_dev_alias_p(int _flags, struct cdev **_cdev, struct cdev *_pdev, const char *_fmt, ...) __printflike(4, 5); int make_dev_physpath_alias(int _flags, struct cdev **_cdev, struct cdev *_pdev, struct cdev *_old_alias, const char *_physpath); void dev_lock(void); void dev_unlock(void); void setconf(void); #ifdef KLD_MODULE #define MAKEDEV_ETERNAL_KLD 0 #else #define MAKEDEV_ETERNAL_KLD MAKEDEV_ETERNAL #endif #define dev2unit(d) ((d)->si_drv0) typedef void d_priv_dtor_t(void *data); int devfs_get_cdevpriv(void **datap); int devfs_set_cdevpriv(void *priv, d_priv_dtor_t *dtr); void devfs_clear_cdevpriv(void); void devfs_fpdrop(struct file *fp); /* XXX This is not public KPI */ ino_t devfs_alloc_cdp_inode(void); void devfs_free_cdp_inode(ino_t ino); #define UID_ROOT 0 #define UID_BIN 3 #define UID_UUCP 66 #define UID_NOBODY 65534 #define GID_WHEEL 0 #define GID_KMEM 2 #define GID_TTY 4 #define GID_OPERATOR 5 #define GID_BIN 7 #define GID_GAMES 13 #define GID_DIALER 68 #define GID_NOBODY 65534 typedef void (*dev_clone_fn)(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **result); int dev_stdclone(char *_name, char **_namep, const char *_stem, int *_unit); EVENTHANDLER_DECLARE(dev_clone, dev_clone_fn); /* Stuff relating to kernel-dump */ struct dumperinfo { dumper_t *dumper; /* Dumping function. */ void *priv; /* Private parts. */ u_int blocksize; /* Size of block in bytes. */ u_int maxiosize; /* Max size allowed for an individual I/O */ off_t mediaoffset; /* Initial offset in bytes. */ off_t mediasize; /* Space available in bytes. */ }; int set_dumper(struct dumperinfo *, const char *_devname, struct thread *td); int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t); void dumpsys(struct dumperinfo *); int doadump(boolean_t); extern int dumping; /* system is dumping */ #endif /* _KERNEL */ #endif /* !_SYS_CONF_H_ */ Index: stable/10 =================================================================== --- stable/10 (revision 299229) +++ stable/10 (revision 299230) Property changes on: stable/10 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r298890