int cac_ioctl_vol(struct cac_softc *sc, struct bioc_vol *bv) { struct cac_drive_info dinfo; struct cac_drive_status dstatus; u_int32_t blks; if (bv->bv_volid > sc->sc_nunits) { return EINVAL; } if (cac_cmd(sc, CAC_CMD_GET_LOG_DRV_INFO, &dinfo, sizeof(dinfo), bv->bv_volid, 0, CAC_CCB_DATA_IN, NULL)) { return EIO; } if (cac_cmd(sc, CAC_CMD_SENSE_DRV_STATUS, &dstatus, sizeof(dstatus), bv->bv_volid, 0, CAC_CCB_DATA_IN, NULL)) { return EIO; } blks = CAC_GET2(dinfo.ncylinders) * CAC_GET1(dinfo.nheads) * CAC_GET1(dinfo.nsectors); bv->bv_size = (off_t)blks * CAC_GET2(dinfo.secsize); bv->bv_level = cac_level[CAC_GET1(dinfo.mirror)]; /*XXX limit check */ bv->bv_nodisk = 0; /* XXX */ bv->bv_status = 0; /* XXX */ bv->bv_percent = -1; bv->bv_seconds = 0; if (dstatus.stat < sizeof(cac_stat)/sizeof(cac_stat[0])) bv->bv_status = cac_stat[dstatus.stat]; if (bv->bv_status == BIOC_SVREBUILD || bv->bv_status == BIOC_SVBUILDING) bv->bv_percent = ((blks - CAC_GET4(dstatus.prog)) * 1000ULL) / blks; return 0; }
void ld_cac_attach(struct device *parent, struct device *self, void *aux) { struct cac_drive_info dinfo; struct cac_attach_args *caca; struct ld_softc *ld; struct ld_cac_softc *sc; struct cac_softc *cac; const char *type; sc = (struct ld_cac_softc *)self; ld = &sc->sc_ld; caca = (struct cac_attach_args *)aux; sc->sc_hwunit = caca->caca_unit; cac = (struct cac_softc *)parent; if (cac_cmd(cac, CAC_CMD_GET_LOG_DRV_INFO, &dinfo, sizeof(dinfo), sc->sc_hwunit, 0, CAC_CCB_DATA_IN, NULL)) { printf("%s: CMD_GET_LOG_DRV_INFO failed\n", self->dv_xname); return; } ld->sc_secsize = CAC_GET2(dinfo.secsize); ld->sc_maxxfer = CAC_MAX_XFER; ld->sc_maxqueuecnt = CAC_MAX_CCBS / cac->sc_nunits; /* XXX */ ld->sc_secperunit = CAC_GET2(dinfo.ncylinders) * CAC_GET1(dinfo.nheads) * CAC_GET1(dinfo.nsectors); ld->sc_start = ld_cac_start; ld->sc_dump = ld_cac_dump; switch (CAC_GET1(dinfo.mirror)) { case 0: type = "standalone disk or RAID0"; break; case 1: type = "RAID4"; break; case 2: type = "RAID1"; break; case 3: type = "RAID5"; break; default: type = "unknown type of"; break; } printf(": %s array\n", type); /* XXX We should verify this... */ ld->sc_flags = LDF_ENABLED; ldattach(ld); }
void ld_cac_attach(device_t parent, device_t self, void *aux) { struct cac_drive_info dinfo; struct cac_attach_args *caca; struct ld_cac_softc *sc = device_private(self); struct cac_softc *cac = device_private(parent); struct ld_softc *ld = &sc->sc_ld; const char *type; caca = aux; ld->sc_dv = self; sc->sc_mutex = &cac->sc_mutex; sc->sc_hwunit = caca->caca_unit; if (cac_cmd(cac, CAC_CMD_GET_LOG_DRV_INFO, &dinfo, sizeof(dinfo), sc->sc_hwunit, 0, CAC_CCB_DATA_IN, NULL)) { aprint_error(": CMD_GET_LOG_DRV_INFO failed\n"); return; } ld->sc_secsize = CAC_GET2(dinfo.secsize); ld->sc_maxxfer = CAC_MAX_XFER; ld->sc_maxqueuecnt = (CAC_MAX_CCBS - 1) / cac->sc_nunits; ld->sc_secperunit = CAC_GET2(dinfo.ncylinders) * CAC_GET1(dinfo.nheads) * CAC_GET1(dinfo.nsectors); ld->sc_start = ld_cac_start; ld->sc_dump = ld_cac_dump; switch (CAC_GET1(dinfo.mirror)) { case 0: type = "standalone disk or RAID0"; break; case 1: type = "RAID4"; break; case 2: type = "RAID1"; break; case 3: type = "RAID5"; break; default: type = "unknown type of"; break; } aprint_normal(": %s array\n", type); /* XXX We should verify this... */ ld->sc_flags = LDF_ENABLED; ldattach(ld); }