static struct xbd_softc * getxbd_softc(dev_t dev) { int unit = XBDUNIT(dev); DPRINTF_FOLLOW(("getxbd_softc(0x%x): major = %d unit = %d\n", dev, major(dev), unit)); #if NXBD > 0 if (major(dev) == xbd_major) return device_lookup(&xbd_cd, unit); #endif #if NWD > 0 if (major(dev) == xbd_wd_major || major(dev) == xbd_wd_cdev_major) return device_lookup(&wd_cd, unit); #endif #if NSD > 0 if (major(dev) == xbd_sd_major || major(dev) == xbd_sd_cdev_major) return device_lookup(&sd_cd, unit); #endif #if NCD > 0 if (major(dev) == xbd_cd_major || major(dev) == xbd_cd_cdev_major) return device_lookup(&cd_cd, unit); #endif return NULL; }
/* * device_open - open the specified device. * * Even if the target driver does not have an open * routine, this function does not return an error. By * using this mechanism, an application can check whether * the specific device exists or not. The open mode * should be handled by an each device driver if it is * needed. */ int device_open(const char *name, int mode, struct device **devp) { struct devops *ops; struct device *dev; int error; sched_lock(); if ((dev = device_lookup(name)) == NULL) { sched_unlock(); return ENXIO; } error = device_reference(dev); if (error) { sched_unlock(); return error; } sched_unlock(); ops = dev->driver->devops; assert(ops->open != NULL); error = (*ops->open)(dev, mode); *devp = dev; device_release(dev); return error; }
int midiopen(dev_t dev, int flags, int mode, struct proc *p) { struct midi_softc *sc; int error; sc = (struct midi_softc *)device_lookup(&midi_cd, minor(dev)); if (sc == NULL) return ENXIO; error = 0; if (sc->flags) { error = EBUSY; goto done; } MIDIBUF_INIT(&sc->inbuf); MIDIBUF_INIT(&sc->outbuf); sc->isbusy = 0; sc->rchan = sc->wchan = 0; sc->async = 0; sc->flags = flags; error = sc->hw_if->open(sc->hw_hdl, flags, midi_iintr, midi_ointr, sc); if (error) sc->flags = 0; done: device_unref(&sc->dev); return error; }
int midiioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) { struct midi_softc *sc; int error; sc = (struct midi_softc *)device_lookup(&midi_cd, minor(dev)); if (sc == NULL) return ENXIO; error = 0; switch(cmd) { case FIONBIO: /* All handled in the upper FS layer */ break; case FIOASYNC: if (*(int *)addr) { if (sc->async) { error = EBUSY; goto done; } sc->async = p; } else sc->async = 0; break; default: error = ENOTTY; } done: device_unref(&sc->dev); return error; }
int prestoopen(dev_t dev, int flag, int fmt, struct proc *proc) { int unit, part; struct presto_softc *sc; unit = DISKUNIT(dev); sc = (struct presto_softc *)device_lookup(&presto_cd, unit); if (sc == NULL) return (ENXIO); /* only allow valid partitions */ part = DISKPART(dev); if (part != RAW_PART && (part >= sc->sc_dk.dk_label->d_npartitions || sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) return (ENXIO); /* update open masks */ switch (fmt) { case S_IFCHR: sc->sc_dk.dk_copenmask |= (1 << part); break; case S_IFBLK: sc->sc_dk.dk_bopenmask |= (1 << part); break; } sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask; return (0); }
int midipoll(dev_t dev, int events, struct proc *p) { struct midi_softc *sc; int revents; sc = (struct midi_softc *)device_lookup(&midi_cd, minor(dev)); if (sc == NULL) return POLLERR; revents = 0; mtx_enter(&audio_lock); if (events & (POLLIN | POLLRDNORM)) { if (!MIDIBUF_ISEMPTY(&sc->inbuf)) revents |= events & (POLLIN | POLLRDNORM); } if (events & (POLLOUT | POLLWRNORM)) { if (!MIDIBUF_ISFULL(&sc->outbuf)) revents |= events & (POLLOUT | POLLWRNORM); } if (revents == 0) { if (events & (POLLIN | POLLRDNORM)) selrecord(p, &sc->rsel); if (events & (POLLOUT | POLLWRNORM)) selrecord(p, &sc->wsel); } mtx_leave(&audio_lock); device_unref(&sc->dev); return (revents); }
struct extent * pciaddr_search(int mem_port, bus_addr_t *startp, bus_size_t size) { extern struct cfdriver pcibios_cd; struct pcibios_softc *sc; sc = (struct pcibios_softc *)device_lookup(&pcibios_cd, 0); if (sc && !(pcibios_flags & PCIBIOS_ADDR_FIXUP)) { struct extent_region *rp; struct extent *ex = mem_port? sc->extent_mem : sc->extent_port; /* Search the PCI I/O memory space extent for free * space that will accommodate size. Remember that the * extent stores allocated space and we're searching * for the gaps. * * If we're at the end or the gap between this region * and the next region big enough, then we're done */ for (rp = LIST_FIRST(&ex->ex_regions); rp && *startp + size > rp->er_start; rp = LIST_NEXT(rp, er_link)) { bus_addr_t new_start; new_start = (rp->er_end - 1 + size) & ~(size - 1); if (new_start > *startp) *startp = new_start; } return (ex); } return (NULL); }
/*ARGSUSED*/ int pcfrtc_write(dev_t dev, struct uio *uio, int flags) { struct pcfrtc_softc *sc; u_int8_t cmdbuf[2]; int a, error; if ((sc = device_lookup(&pcfrtc_cd, minor(dev))) == NULL) return (ENXIO); if (uio->uio_offset >= PCF8583_NVRAM_SIZE) return (EINVAL); if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0) return (error); while (uio->uio_resid && uio->uio_offset < PCF8583_NVRAM_SIZE) { a = (int)uio->uio_offset; cmdbuf[0] = a + PCF8583_NVRAM_START; if ((error = uiomove(&cmdbuf[1], 1, uio)) != 0) break; if ((error = iic_exec(sc->sc_tag, uio->uio_resid ? I2C_OP_WRITE : I2C_OP_WRITE_WITH_STOP, sc->sc_address, cmdbuf, 1, &cmdbuf[1], 1, 0)) != 0) { printf("%s: pcfrtc_write: write failed at 0x%x\n", sc->sc_dev.dv_xname, a); return (error); } } iic_release_bus(sc->sc_tag, 0); return (error); }
/*ARGSUSED*/ int seeprom_read(dev_t dev, struct uio *uio, int flags) { struct seeprom_softc *sc; i2c_addr_t addr; u_int8_t ch, cmdbuf[2]; int a, error; if ((sc = device_lookup(&seeprom_cd, minor(dev))) == NULL) return (ENXIO); if (uio->uio_offset >= sc->sc_size) return (EINVAL); if ((error = iic_acquire_bus(sc->sc_tag, 0)) != 0) return (error); /* * Even though the AT24Cxx EEPROMs support sequential * reads within a page, some I2C controllers do not * support anything other than single-byte transfers, * so we're stuck with this lowest-common-denominator. */ while (uio->uio_resid > 0 && uio->uio_offset < sc->sc_size) { a = (int)uio->uio_offset; if (sc->sc_cmdlen == 1) { addr = sc->sc_address + (a >> 8); cmdbuf[0] = a & 0xff; } else {
static void demo_thread_entry(void) { device_t *testser; char test[260]; unsigned i = 0; unsigned j = 10; //int retcode = 1; printf("START TX\n"); testser = device_lookup("uart",0); if (!testser) { printf("ERROR 1 !!!\n"); } memset(test, 0, sizeof(test)); while (1) { snprintf(test, sizeof(test),teststring,i++); j++; if (j > strlen(test)) { j = 0; memset(test, 0, sizeof(test)); } printf("%s\n",test); //retcode = device_io(testser, FALSE, test, j); //if (retcode < 0) { // printf("ERROR %d !!!\n", retcode); //} //thread_suspend(); thread_delay(500); } }
int ldsize(dev_t dev) { struct ld_softc *sc; int part, unit, omask, size; unit = DISKUNIT(dev); if ((sc = device_lookup(&ld_cd, unit)) == NULL) return (ENODEV); if ((sc->sc_flags & LDF_ENABLED) == 0) return (ENODEV); part = DISKPART(dev); omask = sc->sc_dk.dk_openmask & (1 << part); if (omask == 0 && ldopen(dev, 0, S_IFBLK, NULL) != 0) return (-1); else if (sc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP) size = -1; else size = sc->sc_dk.dk_label->d_partitions[part].p_size * (sc->sc_dk.dk_label->d_secsize / DEV_BSIZE); if (omask == 0 && ldclose(dev, 0, S_IFBLK, NULL) != 0) return (-1); return (size); }
/* * lptread --retrieve printer status in IEEE1284 NIBBLE mode */ int lptread(dev_t dev_id, struct uio *uio, int ioflag) { size_t len = 0; int error = 0; device_t dev = device_lookup(&lpt_cd, LPTUNIT(dev_id)); struct lpt_softc *sc = device_private(dev); if(!(sc->sc_state & HAVEBUS)) { LPT_DPRINTF(("%s(%s): attempt to read using device which does " "not own the bus(%s).\n", __func__, device_xname(dev), device_xname(device_parent(dev)))); return (ENODEV); } sc->sc_state &= ~INTERRUPTED; while (uio->uio_resid) { error = ppbus_read(device_parent(dev), sc->sc_outbuf, min(BUFSIZE, uio->uio_resid), 0, &len); /* If error or no more data, stop */ if (error) { if (error != EWOULDBLOCK) sc->sc_state |= INTERRUPTED; break; } if (len == 0) break; if ((error = uiomove(sc->sc_outbuf, len, uio))) break; } return error; }
/* ARGSUSED */ int ldclose(dev_t dev, int flags, int fmt, struct proc *p) { struct ld_softc *sc; int part, unit; unit = DISKUNIT(dev); part = DISKPART(dev); sc = device_lookup(&ld_cd, unit); ldlock(sc); switch (fmt) { case S_IFCHR: sc->sc_dk.dk_copenmask &= ~(1 << part); break; case S_IFBLK: sc->sc_dk.dk_bopenmask &= ~(1 << part); break; } sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask; if (sc->sc_dk.dk_openmask == 0 && sc->sc_flush != NULL) if ((*sc->sc_flush)(sc) != 0) printf("%s: unable to flush cache\n", sc->sc_dv.dv_xname); ldunlock(sc); return (0); }
int midikqfilter(dev_t dev, struct knote *kn) { struct midi_softc *sc; struct klist *klist; int error; sc = (struct midi_softc *)device_lookup(&midi_cd, minor(dev)); if (sc == NULL) return ENXIO; error = 0; switch (kn->kn_filter) { case EVFILT_READ: klist = &sc->rsel.si_note; kn->kn_fop = &midiread_filtops; break; case EVFILT_WRITE: klist = &sc->wsel.si_note; kn->kn_fop = &midiwrite_filtops; break; default: error = EINVAL; goto done; } kn->kn_hook = (void *)sc; mtx_enter(&audio_lock); SLIST_INSERT_HEAD(klist, kn, kn_selnext); mtx_leave(&audio_lock); done: device_unref(&sc->dev); return error; }
int cgeightopen(dev_t dev, int flags, int mode, struct lwp *l) { int unit = minor(dev); if (device_lookup(&cgeight_cd, unit) == NULL) return (ENXIO); return (0); }
int midi_unit_count(void) { int i; for ( i = 0; i < midi_cd.cd_ndevs; ++i) if (NULL == device_lookup(&midi_cd, i)) break; return i; }
int midiread(dev_t dev, struct uio *uio, int ioflag) { struct midi_softc *sc; struct midi_buffer *mb; size_t count; int error; sc = (struct midi_softc *)device_lookup(&midi_cd, minor(dev)); if (sc == NULL) return ENXIO; if (!(sc->flags & FREAD)) { error = ENXIO; goto done; } mb = &sc->inbuf; /* if there is no data then sleep (unless IO_NDELAY flag is set) */ error = 0; mtx_enter(&audio_lock); while (MIDIBUF_ISEMPTY(mb)) { if (ioflag & IO_NDELAY) { mtx_leave(&audio_lock); error = EWOULDBLOCK; goto done; } sc->rchan = 1; error = msleep(&sc->rchan, &audio_lock, PWAIT | PCATCH, "mid_rd", 0); if (!(sc->dev.dv_flags & DVF_ACTIVE)) error = EIO; if (error) { mtx_leave(&audio_lock); goto done; } } /* at this stage, there is at least 1 byte */ while (uio->uio_resid > 0 && mb->used > 0) { count = MIDIBUF_SIZE - mb->start; if (count > mb->used) count = mb->used; if (count > uio->uio_resid) count = uio->uio_resid; mtx_leave(&audio_lock); error = uiomove(mb->data + mb->start, count, uio); if (error) goto done; mtx_enter(&audio_lock); MIDIBUF_REMOVE(mb, count); } mtx_leave(&audio_lock); done: device_unref(&sc->dev); return error; }
/* * Take a dump. */ int lddump(dev_t dev, daddr_t blkno, caddr_t va, size_t size) { struct ld_softc *sc; struct disklabel *lp; int unit, part, nsects, sectoff, towrt, nblk, maxblkcnt, rv; static int dumping; unit = DISKUNIT(dev); if ((sc = device_lookup(&ld_cd, unit)) == NULL) return (ENXIO); if ((sc->sc_flags & LDF_ENABLED) == 0) return (ENODEV); if (sc->sc_dump == NULL) return (ENXIO); /* Check if recursive dump; if so, punt. */ if (dumping) return (EFAULT); dumping = 1; /* Convert to disk sectors. Request must be a multiple of size. */ part = DISKPART(dev); lp = sc->sc_dk.dk_label; if ((size % lp->d_secsize) != 0) return (EFAULT); towrt = size / lp->d_secsize; blkno = dbtob(blkno) / lp->d_secsize; /* blkno in DEV_BSIZE units */ nsects = lp->d_partitions[part].p_size; sectoff = lp->d_partitions[part].p_offset; /* Check transfer bounds against partition size. */ if ((blkno < 0) || ((blkno + towrt) > nsects)) return (EINVAL); /* Offset block number to start of partition. */ blkno += sectoff; /* Start dumping and return when done. */ maxblkcnt = sc->sc_maxxfer / sc->sc_secsize - 1; while (towrt > 0) { nblk = min(maxblkcnt, towrt); if ((rv = (*sc->sc_dump)(sc, va, blkno, nblk)) != 0) return (rv); towrt -= nblk; blkno += nblk; va += nblk * sc->sc_secsize; } dumping = 0; return (0); }
static int pciopen(dev_t dev, int flags, int mode, struct lwp *l) { device_t dv; dv = device_lookup(&pci_cd, minor(dev)); if (dv == NULL) return ENXIO; return 0; }
/* * Adjust the size of a transfer. */ static void ldminphys(struct buf *bp) { struct ld_softc *sc; sc = device_lookup(&ld_cd, DISKUNIT(bp->b_dev)); if (bp->b_bcount > sc->sc_maxxfer) bp->b_bcount = sc->sc_maxxfer; minphys(bp); }
/*ARGSUSED*/ int pcfrtc_close(dev_t dev, int flag, int fmt, struct proc *p) { struct pcfrtc_softc *sc; if ((sc = device_lookup(&pcfrtc_cd, minor(dev))) == NULL) return (ENXIO); sc->sc_open = 0; return (0); }
/* ARGSUSED */ static void ldshutdown(void *cookie) { struct ld_softc *sc; int i; for (i = 0; i < ld_cd.cd_ndevs; i++) { if ((sc = device_lookup(&ld_cd, i)) == NULL) continue; if (sc->sc_flush != NULL && (*sc->sc_flush)(sc) != 0) printf("%s: unable to flush cache\n", sc->sc_dv.dv_xname); } }
/*ARGSUSED*/ int pcfrtc_open(dev_t dev, int flag, int fmt, struct proc *p) { struct pcfrtc_softc *sc; if ((sc = device_lookup(&pcfrtc_cd, minor(dev))) == NULL) return (ENXIO); /* XXX: Locking */ if (sc->sc_open) return (EBUSY); sc->sc_open = 1; return (0); }
void prestostrategy(struct buf *bp) { int unit, part; struct presto_softc *sc; size_t offset, count; int s; unit = DISKUNIT(bp->b_dev); sc = (struct presto_softc *)device_lookup(&presto_cd, unit); /* Sort rogue requests out */ if (sc == NULL || bp->b_blkno < 0 || (bp->b_bcount % sc->sc_dk.dk_label->d_secsize) != 0) { bp->b_error = EINVAL; goto bad; } /* Do not write on "no trespassing" areas... */ part = DISKPART(bp->b_dev); if (part != RAW_PART && bounds_check_with_label(bp, sc->sc_dk.dk_label, sc->sc_dk.dk_cpulabel, 1) <= 0) goto bad; /* Bound the request size, then move data between buf and nvram */ bp->b_resid = bp->b_bcount; offset = (bp->b_blkno << DEV_BSHIFT) + PSERVE_OFFSET; count = bp->b_bcount; if (count > (sc->sc_memsize - offset)) count = (sc->sc_memsize - offset); if (ISSET(bp->b_flags, B_READ)) bcopy(sc->sc_mem + offset, bp->b_data, count); else bcopy(bp->b_data, sc->sc_mem + offset, count); bp->b_resid -= count; goto done; bad: bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; done: s = splbio(); biodone(bp); splx(s); }
void ldstrategy(struct buf *bp) { struct ld_softc *sc; int s; sc = device_lookup(&ld_cd, DISKUNIT(bp->b_dev)); s = splbio(); if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) { BUFQ_INSERT_TAIL(&sc->sc_bufq, bp); splx(s); return; } splx(s); ldstart(sc, bp); }
/* * lptclose -- close the device, free the local line buffer. * * Check for interrupted write call added. */ int lptclose(dev_t dev_id, int flags, int fmt, struct lwp *l) { device_t dev = device_lookup(&lpt_cd, LPTUNIT(dev_id)); struct lpt_softc *sc = device_private(dev); int err; err = lpt_release_ppbus(sc, PPBUS_WAIT|PPBUS_INTR); if(err) { LPT_DPRINTF(("%s(%s): error (%d) while releasing ppbus.\n", __func__, device_xname(dev), err)); } sc->sc_state = 0; return err; }
int prestosize(dev_t dev) { struct presto_softc *sc; int unit, part; unit = DISKUNIT(dev); sc = (struct presto_softc *)device_lookup(&presto_cd, unit); if (sc == NULL) return (0); part = DISKPART(dev); if (part >= sc->sc_dk.dk_label->d_npartitions) return (0); else return (sc->sc_dk.dk_label->d_partitions[part].p_size * (sc->sc_dk.dk_label->d_secsize / DEV_BSIZE)); }
unsigned dodismount(int argc,char *argv[],int qualc,char *qualv[]) { struct DEV *dev; // note that device lookup interface has changed, fix later register int sts = device_lookup(strlen(argv[1]),argv[1],0,&dev); if (sts & 1) { if (dev->vcb != NULL) { sts = dismount(dev->vcb); } else { sts = SS$_DEVNOTMOUNT; } } if ((sts & 1) == 0) printf("%%DISMOUNT-E-STATUS Error: %d\n",sts); return sts; }
int prestoioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *proc) { struct presto_softc *sc; int unit; int error; unit = DISKUNIT(dev); sc = (struct presto_softc *)device_lookup(&presto_cd, unit); switch (cmd) { case DIOCGDINFO: bcopy(sc->sc_dk.dk_label, data, sizeof(struct disklabel)); return (0); case DIOCSDINFO: if ((flag & FWRITE) == 0) return (EBADF); error = setdisklabel(sc->sc_dk.dk_label, (struct disklabel *)data, /*sd->sc_dk.dk_openmask : */0, sc->sc_dk.dk_cpulabel); return (error); case DIOCWDINFO: if ((flag & FWRITE) == 0) return (EBADF); error = setdisklabel(sc->sc_dk.dk_label, (struct disklabel *)data, /*sd->sc_dk.dk_openmask : */0, sc->sc_dk.dk_cpulabel); if (error == 0) { error = writedisklabel(DISKLABELDEV(dev), prestostrategy, sc->sc_dk.dk_label, sc->sc_dk.dk_cpulabel); } return (error); default: return (EINVAL); } }
/* * lptwrite --copy a line from user space to a local buffer, then call * putc to get the chars moved to the output queue. * * Flagging of interrupted write added. */ int lptwrite(dev_t dev_id, struct uio * uio, int ioflag) { int error=0; size_t n, cnt; device_t dev = device_lookup(&lpt_cd, LPTUNIT(dev_id)); struct lpt_softc * sc = device_private(dev); /* Check state and flags */ if(!(sc->sc_state & HAVEBUS)) { LPT_DPRINTF(("%s(%s): attempt to write using device which does " "not own the bus(%s).\n", __func__, device_xname(dev), device_xname(device_parent(dev)))); return EINVAL; } LPT_VPRINTF(("%s(%s): writing %zu bytes\n", __func__, device_xname(dev), uio->uio_resid)); /* Write the data */ sc->sc_state &= ~INTERRUPTED; while (uio->uio_resid) { n = MIN(BUFSIZE, uio->uio_resid); error = uiomove(sc->sc_inbuf, n, uio); if (error) break; error = ppbus_write(device_parent(dev), sc->sc_inbuf, n, ioflag, &cnt); if (error) { if (error != EWOULDBLOCK) sc->sc_state |= INTERRUPTED; break; } } LPT_VPRINTF(("%s(%s): transfer finished, error %d.\n", __func__, device_xname(dev), error)); return error; }