static const char * rlstate(struct rlc_softc *sc, int unit) { int i = 0; do { RL_WREG(RL_DA, RLDA_GS); RL_WREG(RL_CS, RLCS_GS|(unit << RLCS_USHFT)); waitcrdy(sc); } while (((RL_RREG(RL_CS) & RLCS_ERR) != 0) && i++ < 10); if (i == 10) return NULL; i = RL_RREG(RL_MP) & RLMP_STATUS; return rlstates[i]; }
int rlopen(dev_t dev, int flag, int fmt, struct lwp *l) { struct rl_softc * const rc = device_lookup_private(&rl_cd, DISKUNIT(dev)); struct rlc_softc *sc; int error, part, mask; struct disklabel *dl; const char *msg; /* * Make sure this is a reasonable open request. */ if (rc == NULL) return ENXIO; sc = rc->rc_rlc; part = DISKPART(dev); mutex_enter(&rc->rc_disk.dk_openlock); /* * If there are wedges, and this is not RAW_PART, then we * need to fail. */ if (rc->rc_disk.dk_nwedges != 0 && part != RAW_PART) { error = EBUSY; goto bad1; } /* Check that the disk actually is useable */ msg = rlstate(sc, rc->rc_hwid); if (msg == NULL || msg == rlstates[RLMP_UNLOAD] || msg == rlstates[RLMP_SPUNDOWN]) { error = ENXIO; goto bad1; } /* * If this is the first open; read in where on the disk we are. */ dl = rc->rc_disk.dk_label; if (rc->rc_state == DK_CLOSED) { u_int16_t mp; int maj; RL_WREG(RL_CS, RLCS_RHDR|(rc->rc_hwid << RLCS_USHFT)); waitcrdy(sc); mp = RL_RREG(RL_MP); rc->rc_head = ((mp & RLMP_HS) == RLMP_HS); rc->rc_cyl = (mp >> 7) & 0777; rc->rc_state = DK_OPEN; /* Get disk label */ maj = cdevsw_lookup_major(&rl_cdevsw); if ((msg = readdisklabel(MAKEDISKDEV(maj, device_unit(rc->rc_dev), RAW_PART), rlstrategy, dl, NULL))) aprint_normal_dev(rc->rc_dev, "%s", msg); aprint_normal_dev(rc->rc_dev, "size %d sectors\n", dl->d_secperunit); }
void rlcattach(device_t parent, device_t self, void *aux) { struct rlc_softc *sc = device_private(self); struct uba_attach_args *ua = aux; struct rlc_attach_args ra; int i, error; sc->sc_dev = self; sc->sc_uh = device_private(parent); sc->sc_iot = ua->ua_iot; sc->sc_ioh = ua->ua_ioh; sc->sc_dmat = ua->ua_dmat; uba_intr_establish(ua->ua_icookie, ua->ua_cvec, rlcintr, sc, &sc->sc_intrcnt); evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt, device_xname(sc->sc_dev), "intr"); uba_reset_establish(rlcreset, self); printf("\n"); /* * The RL11 can only have one transfer going at a time, * and max transfer size is one track, so only one dmamap * is needed. */ error = bus_dmamap_create(sc->sc_dmat, MAXRLXFER, 1, MAXRLXFER, 0, BUS_DMA_ALLOCNOW, &sc->sc_dmam); if (error) { aprint_error(": Failed to allocate DMA map, error %d\n", error); return; } bufq_alloc(&sc->sc_q, "disksort", BUFQ_SORT_CYLINDER); for (i = 0; i < RL_MAXDPC; i++) { waitcrdy(sc); RL_WREG(RL_DA, RLDA_GS|RLDA_RST); RL_WREG(RL_CS, RLCS_GS|(i << RLCS_USHFT)); waitcrdy(sc); ra.type = RL_RREG(RL_MP); ra.hwid = i; if ((RL_RREG(RL_CS) & RLCS_ERR) == 0) config_found(sc->sc_dev, &ra, rlcprint); } }
void waitcrdy(struct rlc_softc *sc) { int i; for (i = 0; i < 1000; i++) { DELAY(10000); if (RL_RREG(RL_CS) & RLCS_CRDY) return; } printf("%s: never got ready\n", sc->sc_dev.dv_xname); /* ?panic? */ }
void waitcrdy(struct rlc_softc *sc) { int i; for (i = 0; i < 1000; i++) { DELAY(10000); if (RL_RREG(RL_CS) & RLCS_CRDY) return; } aprint_error_dev(sc->sc_dev, "never got ready\n"); /* ?panic? */ }
/* * Force the controller to interrupt. */ int rlcmatch(struct device *parent, struct cfdata *cf, void *aux) { struct uba_attach_args *ua = aux; struct rlc_softc ssc, *sc = &ssc; int i; sc->sc_iot = ua->ua_iot; sc->sc_ioh = ua->ua_ioh; /* Force interrupt by issuing a "Get Status" command */ RL_WREG(RL_DA, RLDA_GS); RL_WREG(RL_CS, RLCS_GS|RLCS_IE); for (i = 0; i < 100; i++) { DELAY(100000); if (RL_RREG(RL_CS) & RLCS_CRDY) return 1; } return 0; }
int rlopen(dev_t dev, int flag, int fmt, struct proc *p) { int part, unit, mask; struct disklabel *dl; struct rlc_softc *sc; struct rl_softc *rc; char *msg; /* * Make sure this is a reasonable open request. */ unit = DISKUNIT(dev); if (unit >= rl_cd.cd_ndevs) return ENXIO; rc = rl_cd.cd_devs[unit]; if (rc == 0) return ENXIO; sc = (struct rlc_softc *)rc->rc_dev.dv_parent; /* XXX - check that the disk actually is useable */ /* * If this is the first open; read in where on the disk we are. */ dl = rc->rc_disk.dk_label; if (rc->rc_state == DK_CLOSED) { u_int16_t mp; RL_WREG(RL_CS, RLCS_RHDR|(rc->rc_hwid << RLCS_USHFT)); waitcrdy(sc); mp = RL_RREG(RL_MP); rc->rc_head = ((mp & RLMP_HS) == RLMP_HS); rc->rc_cyl = (mp >> 7) & 0777; rc->rc_state = DK_OPEN; /* Get disk label */ printf("%s: ", rc->rc_dev.dv_xname); if ((msg = readdisklabel(MAKEDISKDEV(RLMAJOR, rc->rc_dev.dv_unit, RAW_PART), rlstrategy, dl, NULL))) printf("%s: ", msg); printf("size %d sectors\n", dl->d_secperunit); }