+ /*
+ * Implement inter-read delay
+ */
+ if (sc->sc_delay > 0) {
+ sc->sc_flags |= PPIF_DELAY;
+ timeout(ppistart, unit, sc->sc_delay);
+ error = tsleep(sc, PCATCH|PZERO+1, "hpib", 0);
+ if (error) {
+ splx(s);
+ break;
+ }
+ }
+ splx(s);
+ /*
+ * Must not call uiomove again til we've used all data
+ * that we already grabbed.
+ */
+ if (uio->uio_rw == UIO_WRITE && cnt != len) {
+ cp += cnt;
+ len -= cnt;
+ cnt = 0;
+ goto again;
+ }
+ }
+ s = splsoftclock();
+ if (sc->sc_flags & PPIF_TIMO) {
+ untimeout(ppitimo, unit);
+ sc->sc_flags &= ~PPIF_TIMO;
+ }
+ if (sc->sc_flags & PPIF_DELAY) {
+ untimeout(ppistart, unit);
+ sc->sc_flags &= ~PPIF_DELAY;
+ }
+ splx(s);
+ /*
+ * Adjust for those chars that we uiomove'ed but never wrote
+ */
+ if (uio->uio_rw == UIO_WRITE && cnt != len) {
+ uio->uio_resid += (len - cnt);
+#ifdef DEBUG
+ if (ppidebug & PDB_IO)
+ printf("ppirw: short write, adjust by %d\n",
+ len-cnt);
+#endif
+ }
+ free(buf, M_DEVBUF);
+#ifdef DEBUG
+ if (ppidebug & (PDB_FOLLOW|PDB_IO))
+ printf("ppirw: return %d, resid %d\n", error, uio->uio_resid);
+#endif
+ return (error);
+}
+
+ppiioctl(dev, cmd, data, flag)
+ dev_t dev;
+ int cmd;
+ caddr_t data;
+ int flag;
+{
+ struct ppi_softc *sc = &ppi_softc[UNIT(dev)];
+ struct ppiparam *pp, *upp;
+ int error = 0;
+
+ switch (cmd) {
+ case PPIIOCGPARAM:
+ pp = &sc->sc_param;
+ upp = (struct ppiparam *)data;
+ upp->burst = pp->burst;
+ upp->timo = ppihztoms(pp->timo);
+ upp->delay = ppihztoms(pp->delay);
+ break;
+ case PPIIOCSPARAM:
+ pp = &sc->sc_param;
+ upp = (struct ppiparam *)data;
+ if (upp->burst < PPI_BURST_MIN || upp->burst > PPI_BURST_MAX ||
+ upp->delay < PPI_DELAY_MIN || upp->delay > PPI_DELAY_MAX)
+ return(EINVAL);
+ pp->burst = upp->burst;
+ pp->timo = ppimstohz(upp->timo);
+ pp->delay = ppimstohz(upp->delay);
+ break;
+ case PPIIOCSSEC:
+ sc->sc_sec = *(int *)data;
+ break;
+ default:
+ return(EINVAL);