Lines Matching refs:sc
186 static int wtwait(struct wt_softc *sc, int catch, const char *msg);
187 static int wtcmd(struct wt_softc *sc, int cmd);
188 static int wtstart(struct wt_softc *sc, int flag, void *vaddr, size_t len);
189 static void wtdma(struct wt_softc *sc);
191 static void wtclock(struct wt_softc *sc);
193 static int wtsense(struct wt_softc *sc, int verbose, int ignore);
194 static int wtstatus(struct wt_softc *sc);
195 static void wtrewind(struct wt_softc *sc);
196 static int wtreadfm(struct wt_softc *sc);
197 static int wtwritefm(struct wt_softc *sc);
198 static u_char wtsoft(struct wt_softc *sc, int mask, int bits);
199 static int wtintr(void *sc);
279 struct wt_softc *sc = device_private(self); in wtattach() local
285 sc->sc_dev = self; in wtattach()
293 sc->sc_iot = iot; in wtattach()
294 sc->sc_ioh = ioh; in wtattach()
295 sc->sc_ic = ia->ia_ic; in wtattach()
297 callout_init(&sc->sc_timer_ch, 0); in wtattach()
301 sc->type = WANGTEK; in wtattach()
302 memcpy(&sc->regs, &wtregs, sizeof(sc->regs)); in wtattach()
309 sc->type = ARCHIVE; in wtattach()
310 memcpy(&sc->regs, &avregs, sizeof(sc->regs)); in wtattach()
313 bus_space_write_1(iot, ioh, sc->regs.RDMAPORT, 0); in wtattach()
322 sc->flags = TPSTART; /* tape is rewound */ in wtattach()
323 sc->dens = -1; /* unknown density */ in wtattach()
325 sc->chan = ia->ia_drq[0].ir_drq; in wtattach()
327 if ((maxsize = isa_dmamaxsize(sc->sc_ic, sc->chan)) < MAXPHYS) { in wtattach()
328 aprint_error_dev(sc->sc_dev, in wtattach()
334 if (isa_drq_alloc(sc->sc_ic, sc->chan) != 0) { in wtattach()
335 aprint_error_dev(sc->sc_dev, "can't reserve drq %d\n", in wtattach()
336 sc->chan); in wtattach()
340 if (isa_dmamap_create(sc->sc_ic, sc->chan, MAXPHYS, in wtattach()
342 aprint_error_dev(sc->sc_dev, "can't set up ISA DMA map\n"); in wtattach()
346 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, in wtattach()
347 IST_EDGE, IPL_BIO, wtintr, sc); in wtattach()
373 struct wt_softc *sc; in wtopen() local
376 sc = device_lookup_private(&wt_cd, unit); in wtopen()
377 if (sc == NULL) in wtopen()
381 if (sc->flags & TPINUSE) in wtopen()
385 if (sc->flags & TPSTART) { in wtopen()
387 if ((error = wtwait(sc, PCATCH, "wtrew")) != 0) in wtopen()
391 if (!wtsense(sc, 0, (flag & FWRITE) ? 0 : TP_WRP)) { in wtopen()
393 if (!wtreset(sc->sc_iot, sc->sc_ioh, &sc->regs)) in wtopen()
395 if (!wtsense(sc, 1, (flag & FWRITE) ? 0 : TP_WRP)) in wtopen()
400 if (sc->dens != (minor(dev) & WT_DENSEL)) { in wtopen()
422 if (!wtcmd(sc, d)) in wtopen()
424 if (!wtsense(sc, 1, TP_WRP | TP_ILL)) in wtopen()
428 if (sc->error & TP_ILL) { in wtopen()
429 aprint_error_dev(sc->sc_dev, in wtopen()
434 sc->dens = minor(dev) & WT_DENSEL; in wtopen()
436 sc->flags &= ~TPSTART; in wtopen()
437 } else if (sc->dens != (minor(dev) & WT_DENSEL)) in wtopen()
440 sc->bsize = (minor(dev) & WT_BSIZE) ? 1024 : 512; in wtopen()
441 sc->buf = kmem_alloc(sc->bsize, KM_SLEEP); in wtopen()
443 sc->flags = TPINUSE; in wtopen()
445 sc->flags |= TPREAD; in wtopen()
447 sc->flags |= TPWRITE; in wtopen()
457 struct wt_softc *sc; in wtclose() local
459 sc = device_lookup_private(&wt_cd, minor(dev) & T_UNIT); in wtclose()
462 if (sc->flags & TPREW) in wtclose()
466 if (sc->flags & TPRMARK) { in wtclose()
471 wtwait(sc, 0, "wtrfm"); in wtclose()
474 if (sc->flags & TPWANY) { in wtclose()
476 wtwritefm(sc); in wtclose()
482 wtrewind(sc); in wtclose()
485 if ((sc->flags & TPRANY) && (sc->flags & (TPVOL | TPWANY)) == 0) { in wtclose()
488 wtreadfm(sc); in wtclose()
492 sc->flags &= TPREW | TPRMARK | TPSTART | TPTIMER; in wtclose()
493 kmem_free(sc->buf, sc->bsize); in wtclose()
508 struct wt_softc *sc; in wtioctl() local
511 sc = device_lookup_private(&wt_cd, minor(dev) & T_UNIT); in wtioctl()
522 if ((sc->flags & TPWRITE) == 0 || (sc->flags & TPWP)) in wtioctl()
524 if ((error = wtwait(sc, PCATCH, "wterase")) != 0) in wtioctl()
528 if ((error = wtwait(sc, PCATCH, "wtretens")) != 0) in wtioctl()
534 sc->flags &= ~(TPRO | TPWO | TPVOL); in wtioctl()
535 if (!wtcmd(sc, op)) in wtioctl()
537 sc->flags |= TPSTART | TPREW; in wtioctl()
539 sc->flags |= TPWANY; in wtioctl()
540 wtclock(sc); in wtioctl()
547 sc->type == ARCHIVE ? MT_ISVIPER1 : 0x11; in wtioctl()
548 ((struct mtget*)addr)->mt_dsreg = sc->flags; /* status */ in wtioctl()
549 ((struct mtget*)addr)->mt_erreg = sc->error; /* errors */ in wtioctl()
572 if (sc->flags & TPREW) /* rewind is running */ in wtioctl()
574 if ((error = wtwait(sc, PCATCH, "wtorew")) != 0) in wtioctl()
576 wtrewind(sc); in wtioctl()
581 if ((error = wtwait(sc, PCATCH, "wtorfm")) != 0) in wtioctl()
583 if ((error = wtreadfm(sc)) != 0) in wtioctl()
588 if ((sc->flags & TPWRITE) == 0 || (sc->flags & TPWP)) in wtioctl()
590 if ((error = wtwait(sc, PCATCH, "wtowfm")) != 0) in wtioctl()
592 if ((error = wtwritefm(sc)) != 0) in wtioctl()
608 struct wt_softc *sc; in wtstrategy() local
611 sc = device_lookup_private(&wt_cd, minor(bp->b_dev) & T_UNIT); in wtstrategy()
616 if (sc->flags & TPVOL) in wtstrategy()
621 if ((sc->flags & TPREAD) == 0 || (sc->flags & TPWANY)) in wtstrategy()
626 if ((sc->flags & TPRO) == 0) { in wtstrategy()
627 if (!wtsense(sc, 1, TP_WRP)) { in wtstrategy()
631 if (!wtcmd(sc, QIC_RDDATA)) { in wtstrategy()
633 wtsense(sc, 1, TP_WRP); in wtstrategy()
636 sc->flags |= TPRO | TPRANY; in wtstrategy()
641 if ((sc->flags & TPWRITE) == 0 || (sc->flags & (TPWP | TPRANY))) in wtstrategy()
645 if ((sc->flags & TPWO) == 0) { in wtstrategy()
646 if (!wtsense(sc, 1, 0)) { in wtstrategy()
650 if (!wtcmd(sc, QIC_WRTDATA)) { in wtstrategy()
652 wtsense(sc, 1, 0); in wtstrategy()
655 sc->flags |= TPWO | TPWANY; in wtstrategy()
662 sc->flags &= ~TPEXCEP; in wtstrategy()
664 if (wtstart(sc, bp->b_flags, bp->b_data, bp->b_bcount)) { in wtstrategy()
665 wtwait(sc, 0, (bp->b_flags & B_READ) ? "wtread" : "wtwrite"); in wtstrategy()
666 bp->b_resid -= sc->dmacount; in wtstrategy()
670 if (sc->flags & TPEXCEP) { in wtstrategy()
699 struct wt_softc *sc = arg; in wtintr() local
703 x = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->regs.STATPORT); in wtintr()
705 if ((x & (sc->regs.BUSY | sc->regs.NOEXCEP)) in wtintr()
706 == (sc->regs.BUSY | sc->regs.NOEXCEP)) { in wtintr()
714 if (sc->flags & TPREW) { in wtintr()
715 WTDBPRINT(((x & (sc->regs.BUSY | sc->regs.NOEXCEP)) in wtintr()
716 == (sc->regs.BUSY | sc->regs.NOEXCEP) ? in wtintr()
718 sc->flags &= ~TPREW; /* rewind finished */ in wtintr()
719 wtsense(sc, 1, TP_WRP); in wtintr()
720 wakeup((void *)sc); in wtintr()
727 if (sc->flags & (TPRMARK | TPWMARK)) { in wtintr()
728 WTDBPRINT(((x & (sc->regs.BUSY | sc->regs.NOEXCEP)) in wtintr()
729 == (sc->regs.BUSY | sc->regs.NOEXCEP) ? in wtintr()
731 if ((x & sc->regs.NOEXCEP) == 0) /* operation failed */ in wtintr()
732 wtsense(sc, 1, (sc->flags & TPRMARK) ? TP_WRP : 0); in wtintr()
733 sc->flags &= ~(TPRMARK | TPWMARK); /* operation finished */ in wtintr()
734 wakeup((void *)sc); in wtintr()
741 if ((sc->flags & TPACTIVE) == 0) { in wtintr()
745 sc->flags &= ~TPACTIVE; in wtintr()
746 sc->dmacount += sc->bsize; /* increment counter */ in wtintr()
751 if ((sc->dmaflags & DMAMODE_READ) && in wtintr()
752 (sc->dmatotal - sc->dmacount) < sc->bsize) { in wtintr()
755 isa_dmadone(sc->sc_ic, sc->chan); in wtintr()
756 memcpy(sc->dmavaddr, sc->buf, sc->dmatotal - sc->dmacount); in wtintr()
758 isa_dmadone(sc->sc_ic, sc->chan); in wtintr()
763 if ((x & sc->regs.NOEXCEP) == 0) { in wtintr()
765 wtsense(sc, 1, (sc->dmaflags & DMAMODE_READ) ? TP_WRP : 0); in wtintr()
766 if (sc->error & (TP_EOM | TP_FIL)) in wtintr()
767 sc->flags |= TPVOL; /* end of file */ in wtintr()
769 sc->flags |= TPEXCEP; /* i/o error */ in wtintr()
770 wakeup((void *)sc); in wtintr()
774 if (sc->dmacount < sc->dmatotal) { in wtintr()
776 sc->dmavaddr = (char *)sc->dmavaddr + sc->bsize; in wtintr()
777 wtdma(sc); in wtintr()
778 WTDBPRINT(("continue i/o, %d\n", sc->dmacount)); in wtintr()
781 if (sc->dmacount > sc->dmatotal) /* short last block */ in wtintr()
782 sc->dmacount = sc->dmatotal; in wtintr()
784 wakeup((void *)sc); in wtintr()
785 WTDBPRINT(("i/o finished, %d\n", sc->dmacount)); in wtintr()
791 wtrewind(struct wt_softc *sc) in wtrewind() argument
793 int rwmode = sc->flags & (TPRO | TPWO); in wtrewind()
795 sc->flags &= ~(TPRO | TPWO | TPVOL); in wtrewind()
802 if (sc->type == WANGTEK && rwmode) { in wtrewind()
803 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->regs.CTLPORT, 0); in wtrewind()
804 } else if (!wtcmd(sc, QIC_REWIND)) in wtrewind()
806 sc->flags |= TPSTART | TPREW; in wtrewind()
807 wtclock(sc); in wtrewind()
814 wtreadfm(struct wt_softc *sc) in wtreadfm() argument
817 sc->flags &= ~(TPRO | TPWO | TPVOL); in wtreadfm()
818 if (!wtcmd(sc, QIC_READFM)) { in wtreadfm()
819 wtsense(sc, 1, TP_WRP); in wtreadfm()
822 sc->flags |= TPRMARK | TPRANY; in wtreadfm()
823 wtclock(sc); in wtreadfm()
832 wtwritefm(struct wt_softc *sc) in wtwritefm() argument
836 sc->flags &= ~(TPRO | TPWO); in wtwritefm()
837 if (!wtcmd(sc, QIC_WRITEFM)) { in wtwritefm()
838 wtsense(sc, 1, 0); in wtwritefm()
841 sc->flags |= TPWMARK | TPWANY; in wtwritefm()
842 wtclock(sc); in wtwritefm()
843 return wtwait(sc, 0, "wtwfm"); in wtwritefm()
850 wtsoft(struct wt_softc *sc, int mask, int bits) in wtsoft() argument
852 bus_space_tag_t iot = sc->sc_iot; in wtsoft()
853 bus_space_handle_t ioh = sc->sc_ioh; in wtsoft()
860 x = bus_space_read_1(iot, ioh, sc->regs.STATPORT); in wtsoft()
866 x = bus_space_read_1(iot, ioh, sc->regs.STATPORT); in wtsoft()
872 x = bus_space_read_1(iot, ioh, sc->regs.STATPORT); in wtsoft()
883 wtcmd(struct wt_softc *sc, int cmd) in wtcmd() argument
885 bus_space_tag_t iot = sc->sc_iot; in wtcmd()
886 bus_space_handle_t ioh = sc->sc_ioh; in wtcmd()
892 x = wtsoft(sc, sc->regs.BUSY | sc->regs.NOEXCEP, in wtcmd()
893 sc->regs.BUSY | sc->regs.NOEXCEP); /* ready? */ in wtcmd()
894 if ((x & sc->regs.NOEXCEP) == 0) { /* error */ in wtcmd()
900 bus_space_write_1(iot, ioh, sc->regs.CMDPORT, cmd); in wtcmd()
903 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, in wtcmd()
904 sc->regs.REQUEST | sc->regs.ONLINE); in wtcmd()
907 wtsoft(sc, sc->regs.BUSY, sc->regs.BUSY); in wtcmd()
910 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, in wtcmd()
911 sc->regs.IEN | sc->regs.ONLINE); in wtcmd()
914 wtsoft(sc, sc->regs.BUSY, 0); in wtcmd()
921 wtwait(struct wt_softc *sc, int catch, const char *msg) in wtwait() argument
926 while (sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK)) in wtwait()
927 if ((error = tsleep((void *)sc, WTPRI | catch, msg, 0)) != 0) in wtwait()
934 wtdma(struct wt_softc *sc) in wtdma() argument
936 bus_space_tag_t iot = sc->sc_iot; in wtdma()
937 bus_space_handle_t ioh = sc->sc_ioh; in wtdma()
939 sc->flags |= TPACTIVE; in wtdma()
940 wtclock(sc); in wtdma()
942 if (sc->type == ARCHIVE) { in wtdma()
944 bus_space_write_1(iot, ioh, sc->regs.SDMAPORT, 0); in wtdma()
947 if ((sc->dmaflags & DMAMODE_READ) && in wtdma()
948 (sc->dmatotal - sc->dmacount) < sc->bsize) { in wtdma()
950 isa_dmastart(sc->sc_ic, sc->chan, sc->buf, in wtdma()
951 sc->bsize, NULL, sc->dmaflags, BUS_DMA_NOWAIT); in wtdma()
953 isa_dmastart(sc->sc_ic, sc->chan, sc->dmavaddr, in wtdma()
954 sc->bsize, NULL, sc->dmaflags, BUS_DMA_NOWAIT); in wtdma()
959 wtstart(struct wt_softc *sc, int flag, void *vaddr, size_t len) in wtstart() argument
964 x = wtsoft(sc, sc->regs.BUSY | sc->regs.NOEXCEP, in wtstart()
965 sc->regs.BUSY | sc->regs.NOEXCEP); /* ready? */ in wtstart()
966 if ((x & sc->regs.NOEXCEP) == 0) { in wtstart()
967 sc->flags |= TPEXCEP; /* error */ in wtstart()
970 sc->flags &= ~TPEXCEP; /* clear exception flag */ in wtstart()
971 sc->dmavaddr = vaddr; in wtstart()
972 sc->dmatotal = len; in wtstart()
973 sc->dmacount = 0; in wtstart()
974 sc->dmaflags = flag & B_READ ? DMAMODE_READ : DMAMODE_WRITE; in wtstart()
975 wtdma(sc); in wtstart()
983 wtclock(struct wt_softc *sc) in wtclock() argument
986 if (sc->flags & TPTIMER) in wtclock()
988 sc->flags |= TPTIMER; in wtclock()
993 callout_reset(&sc->sc_timer_ch, (sc->flags & TPACTIVE) ? 1 : hz, in wtclock()
994 wttimer, sc); in wtclock()
1005 register struct wt_softc *sc = (struct wt_softc *)arg; in wttimer() local
1009 sc->flags &= ~TPTIMER; in wttimer()
1010 if ((sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK)) == 0) in wttimer()
1015 status = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->regs.STATPORT); in wttimer()
1016 if ((status & (sc->regs.BUSY | sc->regs.NOEXCEP)) in wttimer()
1017 != (sc->regs.BUSY | sc->regs.NOEXCEP)) { in wttimer()
1019 wtintr(sc); in wttimer()
1024 if (sc->flags & (TPACTIVE | TPREW | TPRMARK | TPWMARK)) in wttimer()
1025 wtclock(sc); in wttimer()
1064 wtsense(struct wt_softc *sc, int verbose, int ignore) in wtsense() argument
1070 sc->flags &= ~(TPRO | TPWO); in wtsense()
1071 if (!wtstatus(sc)) in wtsense()
1073 if ((sc->error & TP_ST0) == 0) in wtsense()
1074 sc->error &= ~TP_ST0MASK; in wtsense()
1075 if ((sc->error & TP_ST1) == 0) in wtsense()
1076 sc->error &= ~TP_ST1MASK; in wtsense()
1077 sc->error &= ~ignore; /* ignore certain errors */ in wtsense()
1078 error = sc->error & (TP_FIL | TP_BNL | TP_UDA | TP_EOM | TP_WRP | in wtsense()
1090 else if ((error & TP_WRP) && (sc->flags & TPWP) == 0) { in wtsense()
1092 sc->flags |= TPWP; in wtsense()
1106 printf("%s: %s\n", device_xname(sc->sc_dev), msg); in wtsense()
1114 wtstatus(struct wt_softc *sc) in wtstatus() argument
1116 bus_space_tag_t iot = sc->sc_iot; in wtstatus()
1117 bus_space_handle_t ioh = sc->sc_ioh; in wtstatus()
1122 wtsoft(sc, sc->regs.BUSY | sc->regs.NOEXCEP, in wtstatus()
1123 sc->regs.BUSY | sc->regs.NOEXCEP); /* ready? */ in wtstatus()
1125 bus_space_write_1(iot, ioh, sc->regs.CMDPORT, QIC_RDSTAT); in wtstatus()
1128 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, in wtstatus()
1129 sc->regs.REQUEST | sc->regs.ONLINE); in wtstatus()
1132 wtsoft(sc, sc->regs.BUSY, sc->regs.BUSY); in wtstatus()
1134 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, sc->regs.ONLINE); in wtstatus()
1137 wtsoft(sc, sc->regs.BUSY, 0); in wtstatus()
1139 p = (char *)&sc->error; in wtstatus()
1140 while (p < (char *)&sc->error + 6) { in wtstatus()
1141 u_char x = wtsoft(sc, sc->regs.BUSY | sc->regs.NOEXCEP, in wtstatus()
1142 sc->regs.BUSY | sc->regs.NOEXCEP); in wtstatus()
1144 if ((x & sc->regs.NOEXCEP) == 0) { /* error */ in wtstatus()
1150 *p++ = bus_space_read_1(iot, ioh, sc->regs.DATAPORT); in wtstatus()
1153 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, in wtstatus()
1154 sc->regs.REQUEST | sc->regs.ONLINE); in wtstatus()
1157 wtsoft(sc, sc->regs.BUSY, 0); in wtstatus()
1160 bus_space_write_1(iot, ioh, sc->regs.CTLPORT, sc->regs.ONLINE); in wtstatus()