static int fw_write (struct dev_write_args *ap) { cdev_t dev = ap->a_head.a_dev; struct uio *uio = ap->a_uio; int err = 0; struct firewire_softc *sc; int unit = DEV2UNIT(dev); int slept = 0; struct fw_pkt *fp; struct fw_xferq *it; if (DEV_FWMEM(dev)) return physwrite(ap); sc = devclass_get_softc(firewire_devclass, unit); it = ((struct fw_drv1 *)dev->si_drv1)->it; if (it == NULL || it->buf == NULL) return (EIO); isoloop: if (it->stproc == NULL) { it->stproc = STAILQ_FIRST(&it->stfree); if (it->stproc != NULL) { crit_enter(); STAILQ_REMOVE_HEAD(&it->stfree, link); crit_exit(); it->queued = 0; } else if (slept == 0) { slept = 1; err = sc->fc->itx_enable(sc->fc, it->dmach); if (err) return err; err = tsleep(it, FWPRI, "fw_write", hz); if (err) return err; goto isoloop; } else { err = EIO; return err; } } 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) { crit_enter(); STAILQ_INSERT_TAIL(&it->stvalid, it->stproc, link); crit_exit(); it->stproc = NULL; err = sc->fc->itx_enable(sc->fc, it->dmach); } if (uio->uio_resid >= sizeof(struct fw_isohdr)) { slept = 0; goto isoloop; } return err; }
/* * Perform a write to flush the buffer. */ void fl_write( void ) { int err; int nbytes = blocksize; #ifndef MSDOS rewrite: #endif #if defined(MSDOS) && !defined(__NO_PHYS__) if (f_phys) err = physwrite(ar_block->charptr, nbytes); else #endif err = write(archive, ar_block->charptr, nbytes); if (err == nbytes) return; /* multi-volume support on write -- JER */ if (err < 0) perror(ar_file); else #ifdef MSDOS /* DOS version handles volume change in low-level I/O code */ fprintf(stderr, "tar: %s: write failed, short %d bytes\n", ar_file, blocksize - err); #else { sync(); /* have to flush Minix buffer */ uprintf(ftty,"\ntar: Volume full. Change volumes and press [Enter]: "); while (ugetc(ftty)!='\n') ; nbytes -= err; lseek(archive, 0L, 0); goto rewrite; } #endif exit(EX_BADARCH); }