/* * Raw disk read. */ void ideRead(dev_t dev) { if (debugIdeDisk) { printf("----- ideRead dev = 0x%08X -----\n", dev); } physio(ideStrategy, &ideRawBuf, dev, B_READ); }
int wdread(dev_t dev, struct uio *uio, int flags) { WDCDEBUG_PRINT(("wdread\n"), DEBUG_XFERS); return (physio(wdstrategy, dev, B_READ, minphys, uio)); }
/* * Raw disk write. */ void ideWrite(dev_t dev) { if (debugIdeDisk) { printf("----- ideWrite dev = 0x%08X -----\n", dev); } physio(ideStrategy, &ideRawBuf, dev, B_WRITE); }
int wdwrite(dev_t dev, struct uio *uio, int flags) { WDCDEBUG_PRINT(("wdwrite\n"), DEBUG_XFERS); return (physio(wdstrategy, dev, B_WRITE, minphys, uio)); }
int maruwrite(dev_t dev, struct uio *uio, int flags) { ENTERSC(dev); DB("maruwrite(%d, %p, %d)\n", dev, uio, flags); if (!(sc->sc_flags&MUF_INITED)) EXITSC(ENXIO); EXITSC(physio(marustrategy, NULL, dev, B_WRITE, minphys, uio)); }
static int mdwrite(dev_t dev, struct uio *uio, int flags) { struct md_softc *sc; sc = device_lookup_private(&md_cd, MD_UNIT(dev)); if (sc->sc_type == MD_UNCONFIGURED) return ENXIO; return (physio(mdstrategy, NULL, dev, B_WRITE, minphys, uio)); }
/* XXX: we should probably put these into dksubr.c, mostly */ static int cgdwrite(dev_t dev, struct uio *uio, int flags) { struct cgd_softc *cs; struct dk_softc *dksc; DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags)); GETCGD_SOFTC(cs, dev); dksc = &cs->sc_dksc; if (!DK_ATTACHED(dksc)) return ENXIO; return physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio); }
/* XXX: we should probably put these into dksubr.c, mostly */ static int cgdread(dev_t dev, struct uio *uio, int flags) { struct cgd_softc *cs; struct dk_softc *dksc; DPRINTF_FOLLOW(("cgdread(0x%llx, %p, %d)\n", (unsigned long long)dev, uio, flags)); GETCGD_SOFTC(cs, dev); dksc = &cs->sc_dksc; if (!DK_ATTACHED(dksc)) return ENXIO; return physio(cgdstrategy, NULL, dev, B_READ, minphys, uio); }
/* ARGSUSED */ static int vndwrite(dev_t dev, struct uio *uio, int flags) { int unit = vndunit(dev); struct vnd_softc *sc; #ifdef DEBUG if (vnddebug & VDB_FOLLOW) printf("vndwrite(0x%"PRIx64", %p)\n", dev, uio); #endif sc = device_lookup_private(&vnd_cd, unit); if (sc == NULL) return ENXIO; if ((sc->sc_flags & VNF_INITED) == 0) return ENXIO; return physio(vndstrategy, NULL, dev, B_WRITE, minphys, uio); }
/* * Do a read on a device for a user process. * Prime scanner at start of read, check uio values, call ssstrategy * via physio for the actual transfer. */ static int ssread(dev_t dev, struct uio *uio, int flag) { struct ss_softc *ss = device_lookup_private(&ss_cd, SSUNIT(dev)); int error; if (!device_is_active(ss->sc_dev)) return ENODEV; /* if the scanner has not yet been started, do it now */ if (!(ss->flags & SSF_TRIGGERED)) { if (ss->special && ss->special->trigger_scanner) { error = (ss->special->trigger_scanner)(ss); if (error) return (error); } ss->flags |= SSF_TRIGGERED; } return physio(ssstrategy, NULL, dev, B_READ, ssminphys, uio); }
/* ARGSUSED */ int ccdwrite(dev_t dev, struct uio *uio, int flags) { int unit = ccdunit(dev); struct ccd_softc *cs; CCD_DPRINTF(CCDB_FOLLOW, ("ccdwrite(%x, %p)\n", dev, uio)); if (unit >= numccd) return (ENXIO); cs = &ccd_softc[unit]; if ((cs->sc_flags & CCDF_INITED) == 0) return (ENXIO); /* * XXX: It's not clear that using minphys() is completely safe, * in particular, for raw I/O. Underlying devices might have some * non-obvious limits, because of the copy to user-space. */ return (physio(ccdstrategy, NULL, dev, B_WRITE, minphys, uio)); }
/* ARGSUSED */ static int _raw_uread(dev_t fd, uio_t *uiop, cred_t *crp) { return (physio(_raw_strategy, 0, fd, B_READ, minphys, uiop)); }
int bmdwrite(dev_t dev, struct uio *uio, int ioflag) { return physio(bmdstrategy, NULL, dev, B_WRITE, minphys, uio); }
int bmdread(dev_t dev, struct uio *uio, int ioflag) { return physio(bmdstrategy, NULL, dev, B_READ, minphys, uio); }
int fdwrite(dev_t dev, struct uio *uio, int flags) { return (physio(fdstrategy, NULL, dev, B_WRITE, minphys, uio)); }
int sdwrite(dev_t dev, struct uio *uio, int ioflag) { return (physio(sdstrategy, dev, B_WRITE, sdminphys, uio)); }
int sdread(dev_t dev, struct uio *uio, int ioflag) { return (physio(sdstrategy, dev, B_READ, sdminphys, uio)); }
int fw_write(dev_t dev, struct uio *uio, int ioflag) { struct firewire_softc *sc; struct firewire_comm *fc; struct fw_drv1 *d; struct fw_pkt *fp; struct fw_xferq *it; int slept = 0, err = 0; sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev)); if (sc == NULL) return ENXIO; if (DEV_FWMEM(dev)) return physio(fw_strategy, NULL, dev, ioflag, minphys, uio); d = (struct fw_drv1 *)sc->si_drv1; fc = d->fc; it = d->it; if (it == NULL) return fw_write_async(d, uio, ioflag); if (it->buf == NULL) return EIO; mutex_enter(&fc->fc_mtx); isoloop: if (it->stproc == NULL) { it->stproc = STAILQ_FIRST(&it->stfree); if (it->stproc != NULL) { STAILQ_REMOVE_HEAD(&it->stfree, link); 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 mutex_exit(&fc->fc_mtx); err = tsleep(it, FWPRI, "fw_write", hz); mutex_enter(&fc->fc_mtx); if (err) goto out; goto isoloop; } else { err = EIO; goto out; } } mutex_exit(&fc->fc_mtx); fp = (struct fw_pkt *)fwdma_v_addr(it->buf, it->stproc->poffset + it->queued); err = uiomove((void *)fp, sizeof(struct fw_isohdr), uio); if (err != 0) return err; err = uiomove((void *)fp->mode.stream.payload, fp->mode.stream.len, uio); it->queued++; if (it->queued >= it->bnpacket) { STAILQ_INSERT_TAIL(&it->stvalid, it->stproc, link); it->stproc = NULL; err = fc->itx_enable(fc, it->dmach); } if (uio->uio_resid >= sizeof(struct fw_isohdr)) { slept = 0; mutex_enter(&fc->fc_mtx); goto isoloop; } return err; out: mutex_exit(&fc->fc_mtx); return err; }
int fw_read(dev_t dev, struct uio *uio, int ioflag) { struct firewire_softc *sc; struct firewire_comm *fc; struct fw_drv1 *d; struct fw_xferq *ir; struct fw_pkt *fp; int err = 0, slept = 0; sc = device_lookup_private(&ieee1394if_cd, DEV2UNIT(dev)); if (sc == NULL) return ENXIO; if (DEV_FWMEM(dev)) return physio(fw_strategy, NULL, dev, ioflag, minphys, uio); d = (struct fw_drv1 *)sc->si_drv1; fc = d->fc; ir = d->ir; if (ir == NULL) return fw_read_async(d, uio, ioflag); if (ir->buf == NULL) return EIO; mutex_enter(&fc->fc_mtx); readloop: if (ir->stproc == NULL) { /* iso bulkxfer */ ir->stproc = STAILQ_FIRST(&ir->stvalid); if (ir->stproc != NULL) { STAILQ_REMOVE_HEAD(&ir->stvalid, link); ir->queued = 0; } } if (ir->stproc == NULL) { /* no data avaliable */ if (slept == 0) { slept = 1; ir->flag |= FWXFERQ_WAKEUP; mutex_exit(&fc->fc_mtx); err = tsleep(ir, FWPRI, "fw_read", hz); mutex_enter(&fc->fc_mtx); ir->flag &= ~FWXFERQ_WAKEUP; if (err == 0) goto readloop; } else if (slept == 1) err = EIO; mutex_exit(&fc->fc_mtx); return err; } else if (ir->stproc != NULL) { /* iso bulkxfer */ mutex_exit(&fc->fc_mtx); 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) return EIO; err = uiomove((void *)fp, fp->mode.stream.len + sizeof(uint32_t), uio); ir->queued++; if (ir->queued >= ir->bnpacket) { STAILQ_INSERT_TAIL(&ir->stfree, ir->stproc, link); fc->irx_enable(fc, ir->dmach); ir->stproc = NULL; } if (uio->uio_resid >= ir->psize) { slept = -1; mutex_enter(&fc->fc_mtx); goto readloop; } } else mutex_exit(&fc->fc_mtx); return err; }
int cdread(dev_t dev, struct uio *uio, int ioflag) { return (physio(cdstrategy, NULL, dev, B_READ, cdminphys, uio)); }
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 = 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; }
/* ARGSUSED */ static int _raw_uwrite(dev_t fd, uio_t *uiop, cred_t *crp) { return (physio(_raw_strategy, 0, fd, B_WRITE, minphys, uiop)); }
/** * flash_read - read from character device * This function uses the registered driver's read function to read the * requested length to * a buffer and then moves this buffer to userspace. */ int flashread(dev_t dev, struct uio * const uio, int flag) { return physio(flashstrategy, NULL, dev, B_READ, minphys, uio); }
/** * flash_write - write to character device * This function moves the data into a buffer from userspace to kernel space, * then uses the registered driver's write function to write out the data to * the media. */ int flashwrite(dev_t dev, struct uio * const uio, int flag) { return physio(flashstrategy, NULL, dev, B_WRITE, minphys, uio); }
/* * 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 = 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; }
int wdioctl(dev_t dev, u_long xfer, caddr_t addr, int flag, struct proc *p) { struct wd_softc *wd; struct disklabel *lp; int error = 0; WDCDEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS); wd = wdlookup(DISKUNIT(dev)); if (wd == NULL) return ENXIO; if ((wd->sc_flags & WDF_LOADED) == 0) { error = EIO; goto exit; } switch (xfer) { case DIOCRLDINFO: lp = malloc(sizeof(*lp), M_TEMP, M_WAITOK); wdgetdisklabel(dev, wd, lp, 0); bcopy(lp, wd->sc_dk.dk_label, sizeof(*lp)); free(lp, M_TEMP, 0); goto exit; case DIOCGPDINFO: wdgetdisklabel(dev, wd, (struct disklabel *)addr, 1); goto exit; case DIOCGDINFO: *(struct disklabel *)addr = *(wd->sc_dk.dk_label); goto exit; case DIOCGPART: ((struct partinfo *)addr)->disklab = wd->sc_dk.dk_label; ((struct partinfo *)addr)->part = &wd->sc_dk.dk_label->d_partitions[DISKPART(dev)]; goto exit; case DIOCWDINFO: case DIOCSDINFO: if ((flag & FWRITE) == 0) { error = EBADF; goto exit; } if ((error = disk_lock(&wd->sc_dk)) != 0) goto exit; error = setdisklabel(wd->sc_dk.dk_label, (struct disklabel *)addr, wd->sc_dk.dk_openmask); if (error == 0) { if (wd->drvp->state > RECAL) wd->drvp->drive_flags |= DRIVE_RESET; if (xfer == DIOCWDINFO) error = writedisklabel(DISKLABELDEV(dev), wdstrategy, wd->sc_dk.dk_label); } disk_unlock(&wd->sc_dk); goto exit; #ifdef notyet case DIOCWFORMAT: if ((flag & FWRITE) == 0) return EBADF; { struct format_op *fop; struct iovec aiov; struct uio auio; fop = (struct format_op *)addr; aiov.iov_base = fop->df_buf; aiov.iov_len = fop->df_count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_resid = fop->df_count; auio.uio_segflg = 0; auio.uio_offset = fop->df_startblk * wd->sc_dk.dk_label->d_secsize; auio.uio_procp = p; error = physio(wdformat, dev, B_WRITE, minphys, &auio); fop->df_count -= auio.uio_resid; fop->df_reg[0] = wdc->sc_status; fop->df_reg[1] = wdc->sc_error; goto exit; } #endif default: error = wdc_ioctl(wd->drvp, xfer, addr, flag, p); goto exit; } #ifdef DIAGNOSTIC panic("wdioctl: impossible"); #endif exit: device_unref(&wd->sc_dev); return (error); }
/* * Something (e.g. another driver) has called us * with a periph and a scsi-specific ioctl to perform, * better try. If user-level type command, we must * still be running in the context of the calling process */ int scsipi_do_ioctl(struct scsipi_periph *periph, dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) { int error; SC_DEBUG(periph, SCSIPI_DB2, ("scsipi_do_ioctl(0x%lx)\n", cmd)); if (addr == NULL) return EINVAL; /* Check for the safe-ness of this request. */ switch (cmd) { case OSCIOCIDENTIFY: case SCIOCIDENTIFY: break; case SCIOCCOMMAND: if ((((scsireq_t *)addr)->flags & SCCMD_READ) == 0 && (flag & FWRITE) == 0) return (EBADF); break; default: if ((flag & FWRITE) == 0) return (EBADF); } switch (cmd) { case SCIOCCOMMAND: { scsireq_t *screq = (scsireq_t *)addr; struct scsi_ioctl *si; int len; si = si_get(); si->si_screq = *screq; si->si_periph = periph; len = screq->datalen; if (len) { si->si_iov.iov_base = screq->databuf; si->si_iov.iov_len = len; si->si_uio.uio_iov = &si->si_iov; si->si_uio.uio_iovcnt = 1; si->si_uio.uio_resid = len; si->si_uio.uio_offset = 0; si->si_uio.uio_rw = (screq->flags & SCCMD_READ) ? UIO_READ : UIO_WRITE; if ((flag & FKIOCTL) == 0) { si->si_uio.uio_vmspace = l->l_proc->p_vmspace; } else { UIO_SETUP_SYSSPACE(&si->si_uio); } error = physio(scsistrategy, &si->si_bp, dev, (screq->flags & SCCMD_READ) ? B_READ : B_WRITE, periph->periph_channel->chan_adapter->adapt_minphys, &si->si_uio); } else { /* if no data, no need to translate it.. */ si->si_bp.b_flags = 0; si->si_bp.b_data = 0; si->si_bp.b_bcount = 0; si->si_bp.b_dev = dev; si->si_bp.b_proc = l->l_proc; scsistrategy(&si->si_bp); error = si->si_bp.b_error; } *screq = si->si_screq; si_free(si); return (error); } case SCIOCDEBUG: { int level = *((int *)addr); SC_DEBUG(periph, SCSIPI_DB3, ("debug set to %d\n", level)); periph->periph_dbflags = 0; if (level & 1) periph->periph_dbflags |= SCSIPI_DB1; if (level & 2) periph->periph_dbflags |= SCSIPI_DB2; if (level & 4) periph->periph_dbflags |= SCSIPI_DB3; if (level & 8) periph->periph_dbflags |= SCSIPI_DB4; return (0); } case SCIOCRECONFIG: case SCIOCDECONFIG: return (EINVAL); case SCIOCIDENTIFY: { struct scsi_addr *sca = (struct scsi_addr *)addr; switch (scsipi_periph_bustype(periph)) { case SCSIPI_BUSTYPE_SCSI: sca->type = TYPE_SCSI; sca->addr.scsi.scbus = device_unit(device_parent(periph->periph_dev)); sca->addr.scsi.target = periph->periph_target; sca->addr.scsi.lun = periph->periph_lun; return (0); case SCSIPI_BUSTYPE_ATAPI: sca->type = TYPE_ATAPI; sca->addr.atapi.atbus = device_unit(device_parent(periph->periph_dev)); sca->addr.atapi.drive = periph->periph_target; return (0); } return (ENXIO); } #if defined(COMPAT_12) || defined(COMPAT_FREEBSD) /* SCIOCIDENTIFY before ATAPI staff merge */ case OSCIOCIDENTIFY: { struct oscsi_addr *sca = (struct oscsi_addr *)addr; switch (scsipi_periph_bustype(periph)) { case SCSIPI_BUSTYPE_SCSI: sca->scbus = device_unit(device_parent(periph->periph_dev)); sca->target = periph->periph_target; sca->lun = periph->periph_lun; return (0); } return (ENODEV); } #endif default: return (ENOTTY); } #ifdef DIAGNOSTIC panic("scsipi_do_ioctl: impossible"); #endif }
/*ARGSUSED*/ int zvol_read(dev_t dev, uio_t *uiop, cred_t *cr) { return (physio(zvol_strategy, NULL, dev, B_READ, minphys, uiop)); }
int cdwrite(dev_t dev, struct uio *uio, int ioflag) { return (physio(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio)); }
/*ARGSUSED*/ int zvol_write(dev_t dev, uio_t *uiop, cred_t *cr) { return (physio(zvol_strategy, NULL, dev, B_WRITE, minphys, uiop)); }