int satlinkclose(dev_t dev, int flags, int fmt, struct lwp *l) { struct satlink_softc *sc; int s; sc = device_lookup_private(&satlink_cd, minor(dev)); s = splsoftclock(); sc->sc_flags &= ~SATF_ISOPEN; splx(s); isa_dmaabort(sc->sc_ic, sc->sc_drq); callout_stop(&sc->sc_ch); return (0); }
int ad1848_halt_input(void *addr) { struct ad1848_softc *sc = addr; u_char reg; DPRINTF(("ad1848: ad1848_halt_input\n")); reg = ad_read(sc, SP_INTERFACE_CONFIG); ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~CAPTURE_ENABLE)); if (sc->sc_recrun == 1) { isa_dmaabort(sc->sc_isa, sc->sc_recdrq); sc->sc_recrun = 0; } return 0; }
/* * Halt a DMA in progress. */ int ad1848_halt_output(void *addr) { struct ad1848_softc *sc = addr; u_char reg; DPRINTF(("ad1848: ad1848_halt_output\n")); mtx_enter(&audio_lock); reg = ad_read(sc, SP_INTERFACE_CONFIG); ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~PLAYBACK_ENABLE)); if (sc->sc_playrun == 1) { isa_dmaabort(sc->sc_isa, sc->sc_drq); sc->sc_playrun = 0; } mtx_leave(&audio_lock); return 0; }
static void cectimeout(void *v) { struct cec_softc *sc = v; bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; int s; DPRINTF(DBG_FOLLOW, ("cectimeout: sc=%p\n", sc)); s = splbio(); if (sc->sc_flags & CECF_IO) { bus_space_write_1(iot, ioh, NEC7210_IMR1, 0); bus_space_write_2(iot, ioh, NEC7210_IMR2, 0); bus_space_write_1(iot, ioh, NEC7210_AUXMR, AUXCMD_TCA); sc->sc_flags &= ~(CECF_IO | CECF_READ | CECF_TIMO); isa_dmaabort(sc->sc_ic, sc->sc_drq); printf("%s: %s timeout\n", sc->sc_dev.dv_xname, sc->sc_flags & CECF_READ ? "read" : "write"); gpibintr(sc->sc_gpib); } splx(s); }
/* Abort DMA operation over ISA bus */ int atppc_isadma_abort(isa_chipset_tag_t ic, int drq) { isa_dmaabort(ic, drq); return 0; }
static int fdcintr1(struct fdc_softc *fdc) { #define st0 fdc->sc_status[0] #define cyl fdc->sc_status[1] struct fd_softc *fd; struct buf *bp; bus_space_tag_t iot = fdc->sc_iot; bus_space_handle_t ioh = fdc->sc_ioh; int read, head, sec, i, nblks; struct fd_type *type; struct ne7_fd_formb *finfo = NULL; KASSERT(mutex_owned(&fdc->sc_mtx)); if (fdc->sc_state == PROBING) { #ifdef DEBUG printf("fdcintr: got probe interrupt\n"); #endif fdc->sc_probe++; goto out; } loop: /* Is there a drive for the controller to do a transfer with? */ fd = TAILQ_FIRST(&fdc->sc_drives); if (fd == NULL) { fdc->sc_state = DEVIDLE; goto out; } /* Is there a transfer to this drive? If not, deactivate drive. */ bp = BUFQ_PEEK(fd->sc_q); if (bp == NULL) { fd->sc_ops = 0; TAILQ_REMOVE(&fdc->sc_drives, fd, sc_drivechain); fd->sc_active = 0; goto loop; } if (bp->b_flags & B_FORMAT) finfo = (struct ne7_fd_formb *)bp->b_data; switch (fdc->sc_state) { case DEVIDLE: fdc->sc_errors = 0; fd->sc_skip = 0; fd->sc_bcount = bp->b_bcount; fd->sc_blkno = bp->b_blkno / (FDC_BSIZE / DEV_BSIZE); callout_stop(&fd->sc_motoroff_ch); if ((fd->sc_flags & FD_MOTOR_WAIT) != 0) { fdc->sc_state = MOTORWAIT; return 1; } if ((fd->sc_flags & FD_MOTOR) == 0) { /* Turn on the motor, being careful about pairing. */ struct fd_softc *ofd = fdc->sc_fd[fd->sc_drive ^ 1]; if (ofd && ofd->sc_flags & FD_MOTOR) { callout_stop(&ofd->sc_motoroff_ch); ofd->sc_flags &= ~(FD_MOTOR | FD_MOTOR_WAIT); } fd->sc_flags |= FD_MOTOR | FD_MOTOR_WAIT; fd_set_motor(fdc, 0); fdc->sc_state = MOTORWAIT; /* Allow .25s for motor to stabilize. */ callout_reset(&fd->sc_motoron_ch, hz / 4, fd_motor_on, fd); return 1; } /* Make sure the right drive is selected. */ fd_set_motor(fdc, 0); /* fall through */ case DOSEEK: doseek: if (fd->sc_cylin == bp->b_cylinder) goto doio; out_fdc(iot, ioh, NE7CMD_SPECIFY);/* specify command */ out_fdc(iot, ioh, fd->sc_type->steprate); out_fdc(iot, ioh, 6); /* XXX head load time == 6ms */ out_fdc(iot, ioh, NE7CMD_SEEK); /* seek function */ out_fdc(iot, ioh, fd->sc_drive); /* drive number */ out_fdc(iot, ioh, bp->b_cylinder * fd->sc_type->step); fd->sc_cylin = -1; fdc->sc_state = SEEKWAIT; iostat_seek(fd->sc_dk.dk_stats); disk_busy(&fd->sc_dk); callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc); return 1; case DOIO: doio: type = fd->sc_type; if (finfo) fd->sc_skip = (char *)&(finfo->fd_formb_cylno(0)) - (char *)finfo; sec = fd->sc_blkno % type->seccyl; nblks = type->seccyl - sec; nblks = min(nblks, fd->sc_bcount / FDC_BSIZE); nblks = min(nblks, fdc->sc_maxiosize / FDC_BSIZE); fd->sc_nblks = nblks; fd->sc_nbytes = finfo ? bp->b_bcount : nblks * FDC_BSIZE; head = sec / type->sectrac; sec -= head * type->sectrac; #ifdef DIAGNOSTIC { int block; block = (fd->sc_cylin * type->heads + head) * type->sectrac + sec; if (block != fd->sc_blkno) { printf("fdcintr: block %d != blkno " "%" PRId64 "\n", block, fd->sc_blkno); #ifdef DDB Debugger(); #endif } } #endif read = bp->b_flags & B_READ ? DMAMODE_READ : DMAMODE_WRITE; isa_dmastart(fdc->sc_ic, fdc->sc_drq, (char *)bp->b_data + fd->sc_skip, fd->sc_nbytes, NULL, read | DMAMODE_DEMAND, BUS_DMA_NOWAIT); bus_space_write_1(iot, fdc->sc_fdctlioh, 0, type->rate); #ifdef FD_DEBUG printf("fdcintr: %s drive %d track %d head %d sec %d nblks %d\n", read ? "read" : "write", fd->sc_drive, fd->sc_cylin, head, sec, nblks); #endif if (finfo) { /* formatting */ if (out_fdc(iot, ioh, NE7CMD_FORMAT) < 0) { fdc->sc_errors = 4; fdcretry(fdc); goto loop; } out_fdc(iot, ioh, (head << 2) | fd->sc_drive); out_fdc(iot, ioh, finfo->fd_formb_secshift); out_fdc(iot, ioh, finfo->fd_formb_nsecs); out_fdc(iot, ioh, finfo->fd_formb_gaplen); out_fdc(iot, ioh, finfo->fd_formb_fillbyte); } else { if (read) out_fdc(iot, ioh, NE7CMD_READ); /* READ */ else out_fdc(iot, ioh, NE7CMD_WRITE); /* WRITE */ out_fdc(iot, ioh, (head << 2) | fd->sc_drive); out_fdc(iot, ioh, fd->sc_cylin); /* track */ out_fdc(iot, ioh, head); out_fdc(iot, ioh, sec + 1); /* sector +1 */ out_fdc(iot, ioh, type->secsize);/* sector size */ out_fdc(iot, ioh, type->sectrac);/* sectors/track */ out_fdc(iot, ioh, type->gap1); /* gap1 size */ out_fdc(iot, ioh, type->datalen);/* data length */ } fdc->sc_state = IOCOMPLETE; disk_busy(&fd->sc_dk); /* allow 2 seconds for operation */ callout_reset(&fdc->sc_timo_ch, 2 * hz, fdctimeout, fdc); return 1; /* will return later */ case SEEKWAIT: callout_stop(&fdc->sc_timo_ch); fdc->sc_state = SEEKCOMPLETE; /* allow 1/50 second for heads to settle */ callout_reset(&fdc->sc_intr_ch, hz / 50, fdcintrcb, fdc); return 1; case SEEKCOMPLETE: /* no data on seek */ disk_unbusy(&fd->sc_dk, 0, 0); /* Make sure seek really happened. */ out_fdc(iot, ioh, NE7CMD_SENSEI); if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 || cyl != bp->b_cylinder * fd->sc_type->step) { #ifdef FD_DEBUG fdcstatus(fd->sc_dev, 2, "seek failed"); #endif fdcretry(fdc); goto loop; } fd->sc_cylin = bp->b_cylinder; goto doio; case IOTIMEDOUT: isa_dmaabort(fdc->sc_ic, fdc->sc_drq); case SEEKTIMEDOUT: case RECALTIMEDOUT: case RESETTIMEDOUT: fdcretry(fdc); goto loop; case IOCOMPLETE: /* IO DONE, post-analyze */ callout_stop(&fdc->sc_timo_ch); disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid), (bp->b_flags & B_READ)); if (fdcresult(fdc) != 7 || (st0 & 0xf8) != 0) { isa_dmaabort(fdc->sc_ic, fdc->sc_drq); #ifdef FD_DEBUG fdcstatus(fd->sc_dev, 7, bp->b_flags & B_READ ? "read failed" : "write failed"); printf("blkno %llu nblks %d\n", (unsigned long long)fd->sc_blkno, fd->sc_nblks); #endif fdcretry(fdc); goto loop; } isa_dmadone(fdc->sc_ic, fdc->sc_drq); if (fdc->sc_errors) { diskerr(bp, "fd", "soft error (corrected)", LOG_PRINTF, fd->sc_skip / FDC_BSIZE, NULL); printf("\n"); fdc->sc_errors = 0; } fd->sc_blkno += fd->sc_nblks; fd->sc_skip += fd->sc_nbytes; fd->sc_bcount -= fd->sc_nbytes; if (!finfo && fd->sc_bcount > 0) { bp->b_cylinder = fd->sc_blkno / fd->sc_type->seccyl; goto doseek; } fdfinish(fd, bp); goto loop; case DORESET: /* try a reset, keep motor on */ fd_set_motor(fdc, 1); delay(100); fd_set_motor(fdc, 0); fdc->sc_state = RESETCOMPLETE; callout_reset(&fdc->sc_timo_ch, hz / 2, fdctimeout, fdc); return 1; /* will return later */ case RESETCOMPLETE: callout_stop(&fdc->sc_timo_ch); /* clear the controller output buffer */ for (i = 0; i < 4; i++) { out_fdc(iot, ioh, NE7CMD_SENSEI); (void) fdcresult(fdc); } /* fall through */ case DORECAL: out_fdc(iot, ioh, NE7CMD_RECAL); /* recalibrate function */ out_fdc(iot, ioh, fd->sc_drive); fdc->sc_state = RECALWAIT; callout_reset(&fdc->sc_timo_ch, 5 * hz, fdctimeout, fdc); return 1; /* will return later */ case RECALWAIT: callout_stop(&fdc->sc_timo_ch); fdc->sc_state = RECALCOMPLETE; /* allow 1/30 second for heads to settle */ callout_reset(&fdc->sc_intr_ch, hz / 30, fdcintrcb, fdc); return 1; /* will return later */ case RECALCOMPLETE: out_fdc(iot, ioh, NE7CMD_SENSEI); if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 || cyl != 0) { #ifdef FD_DEBUG fdcstatus(fd->sc_dev, 2, "recalibrate failed"); #endif fdcretry(fdc); goto loop; } fd->sc_cylin = 0; goto doseek; case MOTORWAIT: if (fd->sc_flags & FD_MOTOR_WAIT) return 1; /* time's not up yet */ goto doseek; default: fdcstatus(fd->sc_dev, 0, "stray interrupt"); return 1; } #undef st0 #undef cyl out: cv_signal(&fdc->sc_cv); return 1; }